function setProfitColor($el, value) {
    $el.removeClass('text-success text-danger text-secondary');
    let thr = 0;
    if (value > thr) $el.addClass('text-success');
    else if (value < thr) $el.addClass('text-danger');
    else $el.addClass('text-secondary');
}

function setWinRateColor($el, value) {
    $el.removeClass('text-success text-danger text-secondary');
    let thr = 0.5;
    if (value > thr) $el.addClass('text-success');
    else if (value < thr) $el.addClass('text-danger');
    else $el.addClass('text-secondary');
}

function setRRRColor($el, value) {
    $el.removeClass('text-success text-danger text-secondary');
    if (value === '+∞') { $el.addClass('text-success'); return; }
    let thr = 1.5;
    if (value > thr) $el.addClass('text-success');
    else if (value < thr) $el.addClass('text-danger');
}

function setMathExpColor($el, value) {
    $el.removeClass('text-success text-danger text-secondary');
    if (value === '+∞') { $el.addClass('text-success'); return; }
    let thr = 0.2;
    if (value > thr) $el.addClass('text-success');
    else if (value < thr) $el.addClass('text-danger');
}

function ew_updateStats(stats, n) {
    // 保存stats到全局变量
    window.ewStats = stats;
    
    // 检查是否有统计数据，如果没有则显示空状态
    if (!stats.overall || stats.overall.total_trades === 0) {
        // 显示空状态
        document.getElementById('ew_totalTrades').textContent = '0';
        document.getElementById('ew_winningTrades').textContent = '0';
        document.getElementById('ew_losingTrades').textContent = '0';
        document.getElementById('ew_avgWin').textContent = '0.00';
        document.getElementById('ew_avgLoss').textContent = '0.00';
        document.getElementById('ew_maxWin').textContent = '0.00';
        document.getElementById('ew_maxLoss').textContent = '0.00';
        document.getElementById('ew_maxDrawdown').textContent = '0';
        
        $('#ew_totalProfit').text('0.00');
        setProfitColor($('#ew_totalProfit'), '0.00');
        $('#ew_winRate').text('0.00%');
        setWinRateColor($('#ew_winRate'), '0.00');
        $('#ew_profitFactor').text('0.00');
        setRRRColor($('#ew_profitFactor'), '0.00');
        $('#ew_mathexp').text('0.00');
        setMathExpColor($('#ew_mathexp'), '0.00');
        
        // 清空表格
        $('#ew_rthTrades, #ew_ethTrades').text('0');
        $('#ew_rthWinRate, #ew_ethWinRate').text('0.00%');
        $('#ew_rthAvgWin, #ew_ethAvgWin, #ew_rthAvgLoss, #ew_ethAvgLoss').text('0.00');
        $('#ew_rthProfitFactor, #ew_ethProfitFactor').text('0.00');
        $('#ew_rthTotalProfit, #ew_ethTotalProfit').text('0.00');
        $('#ew_rthMathExp, #ew_ethMathExp').text('0.00');
        
        // 清空Long/Short表格
        $('#ew_longTrades, #ew_shortTrades').text('0');
        $('#ew_longWinRate, #ew_shortWinRate').text('0.00%');
        $('#ew_longAvgWin, #ew_shortAvgWin, #ew_longAvgLoss, #ew_shortAvgLoss').text('0.00');
        $('#ew_longProfitFactor, #ew_shortProfitFactor').text('0.00');
        $('#ew_longTotalProfit, #ew_shortTotalProfit').text('0.00');
        $('#ew_longMathExp, #ew_shortMathExp').text('0.00');
        
        // 清空Side表格
        $('#ew_leftTrades, #ew_rightTrades, #ew_midTrades').text('0');
        $('#ew_leftWinRate, #ew_rightWinRate, #ew_midWinRate').text('0.00%');
        $('#ew_leftAvgWin, #ew_rightAvgWin, #ew_midAvgWin, #ew_leftAvgLoss, #ew_rightAvgLoss, #ew_midAvgLoss').text('0.00');
        $('#ew_leftProfitFactor, #ew_rightProfitFactor, #ew_midProfitFactor').text('0.00');
        $('#ew_leftTotalProfit, #ew_rightTotalProfit, #ew_midTotalProfit').text('0.00');
        $('#ew_leftMathExp, #ew_rightMathExp, #ew_midMathExp').text('0.00');
        
        // 清空最大N笔表格
        const visibleColumnsCount = columnConfig.best_worst_columns && columnConfig.best_worst_columns.display_columns ? 
                columnConfig.best_worst_columns.display_columns.filter(col => col.visible).length : 10;
        $('#ew_maxNLossBody, #ew_maxNWinBody').html(`<tr><td colspan="${visibleColumnsCount}" class="text-center text-muted">暂无数据</td></tr>`);
        
        // 清空资金曲线
        if(window.ewEquityChart) {
            window.ewEquityChart.destroy();
            window.ewEquityChart = null;
        }
        
        return;
    }
    
    // 卡片区
    document.getElementById('ew_totalTrades').textContent = stats.overall.total_trades;
    document.getElementById('ew_winningTrades').textContent = stats.overall.winning_trades;
    document.getElementById('ew_losingTrades').textContent = stats.overall.losing_trades;
    document.getElementById('ew_avgWin').textContent = stats.overall.avg_win.toFixed(2);
    document.getElementById('ew_avgLoss').textContent = stats.overall.avg_loss.toFixed(2);
    document.getElementById('ew_maxWin').textContent = (stats.overall.max_n_win && stats.overall.max_n_win[0]) ? stats.overall.max_n_win[0].net_profit_value.toFixed(2) : '';
    document.getElementById('ew_maxLoss').textContent = (stats.overall.max_n_loss && stats.overall.max_n_loss[0]) ? stats.overall.max_n_loss[0].net_profit_value.toFixed(2) : '';
    //document.getElementById('ew_totalProfit').textContent = Math.round(stats.overall.total_profit);
    //document.getElementById('ew_winRate').textContent = Math.round(stats.overall.win_rate) + '%';
    //document.getElementById('ew_profitFactor').textContent = (stats.overall.profit_factor||0).toFixed(2);

    $('#ew_totalProfit').text(stats.overall.total_profit ? stats.overall.total_profit.toFixed(0) : '0.00');
    setProfitColor($('#ew_totalProfit'), stats.overall.total_profit ? stats.overall.total_profit.toFixed(0) : '0.00');
    $('#ew_winRate').text(stats.overall.win_rate ? stats.overall.win_rate.toFixed(0) + '%' : '0.00%');
    setWinRateColor($('#ew_winRate'), stats.overall.win_rate ? stats.overall.win_rate.toFixed(0) : '0.00');

    if (stats.overall.win_rate && stats.overall.win_rate === 100) {
        $('#ew_profitFactor').text('+∞');
        setRRRColor($('#ew_profitFactor'), '+∞');
        $('#ew_mathexp').text('+∞');
        setMathExpColor($('#ew_mathexp'), '+∞');
    } else {
        $('#ew_profitFactor').text((stats.overall.profit_factor||0).toFixed(2));
        setRRRColor($('#ew_profitFactor'), (stats.overall.profit_factor||0).toFixed(2));
        let mathexp = stats.overall.win_rate/100 * stats.overall.profit_factor - (1-stats.overall.win_rate/100);
        $('#ew_mathexp').text(mathexp.toFixed(2));
        setMathExpColor($('#ew_mathexp'), (mathexp.toFixed(2)));
    }



    // 最大回撤（简单实现：资金曲线最大回撤）
    let eq = stats.overall.equity_curve;
    let maxDrawdown = 0, peak = eq[0]||0;
    for(let v of eq){
        if(v>peak) peak=v;
        let dd = peak-v;
        if(dd>maxDrawdown) maxDrawdown=dd;
    }
    document.getElementById('ew_maxDrawdown').textContent = Math.round(maxDrawdown);
    // RTH/ETH表格
    $('#ew_rthTrades').text(stats.session.RTH.total_trades);
    $('#ew_ethTrades').text(stats.session.ETH.total_trades);
    $('#ew_rthWinRate').text(stats.session.RTH.win_rate.toFixed(2)+'%');
    $('#ew_ethWinRate').text(stats.session.ETH.win_rate.toFixed(2)+'%');
    // 平均盈利、平均亏损用红绿色
    let rthAvgWin = stats.session.RTH.avg_win;
    let ethAvgWin = stats.session.ETH.avg_win;
    let rthAvgLoss = stats.session.RTH.avg_loss;
    let ethAvgLoss = stats.session.ETH.avg_loss;
    $('#ew_rthAvgWin').removeClass('text-success text-danger').addClass(rthAvgWin > 0 ? 'text-success' : (rthAvgWin < 0 ? 'text-danger' : '')).text(rthAvgWin.toFixed(2));
    $('#ew_ethAvgWin').removeClass('text-success text-danger').addClass(ethAvgWin > 0 ? 'text-success' : (ethAvgWin < 0 ? 'text-danger' : '')).text(ethAvgWin.toFixed(2));
    $('#ew_rthAvgLoss').removeClass('text-success text-danger').addClass(rthAvgLoss < 0 ? 'text-danger' : (rthAvgLoss > 0 ? 'text-success' : '')).text(rthAvgLoss.toFixed(2));
    $('#ew_ethAvgLoss').removeClass('text-success text-danger').addClass(ethAvgLoss < 0 ? 'text-danger' : (ethAvgLoss > 0 ? 'text-success' : '')).text(ethAvgLoss.toFixed(2));
    // 盈亏比
    if(stats.session.RTH.win_rate === 100) {
        $('#ew_rthProfitFactor').text('+∞');
        setRRRColor($('#ew_rthProfitFactor'), '+∞');
    } else {
        $('#ew_rthProfitFactor').text((stats.session.RTH.profit_factor||0).toFixed(2));
        setRRRColor($('#ew_rthProfitFactor'), (stats.session.RTH.profit_factor||0).toFixed(2));
    }
    if(stats.session.ETH.win_rate === 100) {
        $('#ew_ethProfitFactor').text('+∞');
        setRRRColor($('#ew_ethProfitFactor'), '+∞');
    } else {
        $('#ew_ethProfitFactor').text((stats.session.ETH.profit_factor||0).toFixed(2));
        setRRRColor($('#ew_ethProfitFactor'), (stats.session.ETH.profit_factor||0).toFixed(2));
    }
    // 盈亏用红绿色
    let rthProfit = stats.session.RTH.total_profit;
    let ethProfit = stats.session.ETH.total_profit;
    let rthClass = rthProfit > 0 ? 'text-success' : (rthProfit < 0 ? 'text-danger' : '');
    let ethClass = ethProfit > 0 ? 'text-success' : (ethProfit < 0 ? 'text-danger' : '');
    $('#ew_rthTotalProfit').removeClass('text-success text-danger').addClass(rthClass).text(rthProfit.toFixed(2));
    $('#ew_ethTotalProfit').removeClass('text-success text-danger').addClass(ethClass).text(ethProfit.toFixed(2));

    // 数学期望
    let rthMathExp = stats.session.RTH.win_rate/100 * stats.session.RTH.profit_factor - (1-stats.session.RTH.win_rate/100);
    let ethMathExp = stats.session.ETH.win_rate/100 * stats.session.ETH.profit_factor - (1-stats.session.ETH.win_rate/100);
    if(stats.session.RTH.win_rate === 100) {
        $('#ew_rthMathExp').text('+∞');
        setMathExpColor($('#ew_rthMathExp'), '+∞');
    } else {
        $('#ew_rthMathExp').text(rthMathExp.toFixed(2));
        setMathExpColor($('#ew_rthMathExp'), rthMathExp.toFixed(2));
    }
    if(stats.session.ETH.win_rate === 100) {
        $('#ew_ethMathExp').text('+∞');
        setMathExpColor($('#ew_ethMathExp'), '+∞');
    } else {
        $('#ew_ethMathExp').text(ethMathExp.toFixed(2));
        setMathExpColor($('#ew_ethMathExp'), ethMathExp.toFixed(2));
    }
    
    // Long/Short表格
    $('#ew_longTrades').text(stats.direction.Long.total_trades);
    $('#ew_shortTrades').text(stats.direction.Short.total_trades);
    $('#ew_longWinRate').text(stats.direction.Long.win_rate.toFixed(2)+'%');
    $('#ew_shortWinRate').text(stats.direction.Short.win_rate.toFixed(2)+'%');
    // 平均盈利、平均亏损用红绿色
    let longAvgWin = stats.direction.Long.avg_win;
    let shortAvgWin = stats.direction.Short.avg_win;
    let longAvgLoss = stats.direction.Long.avg_loss;
    let shortAvgLoss = stats.direction.Short.avg_loss;
    $('#ew_longAvgWin').removeClass('text-success text-danger').addClass(longAvgWin > 0 ? 'text-success' : (longAvgWin < 0 ? 'text-danger' : '')).text(longAvgWin.toFixed(2));
    $('#ew_shortAvgWin').removeClass('text-success text-danger').addClass(shortAvgWin > 0 ? 'text-success' : (shortAvgWin < 0 ? 'text-danger' : '')).text(shortAvgWin.toFixed(2));
    $('#ew_longAvgLoss').removeClass('text-success text-danger').addClass(longAvgLoss < 0 ? 'text-danger' : (longAvgLoss > 0 ? 'text-success' : '')).text(longAvgLoss.toFixed(2));
    $('#ew_shortAvgLoss').removeClass('text-success text-danger').addClass(shortAvgLoss < 0 ? 'text-danger' : (shortAvgLoss > 0 ? 'text-success' : '')).text(shortAvgLoss.toFixed(2));
    // 盈亏比
    if(stats.direction.Long.win_rate === 100) {
        $('#ew_longProfitFactor').text('+∞');
        setRRRColor($('#ew_longProfitFactor'), '+∞');
    } else {
        $('#ew_longProfitFactor').text((stats.direction.Long.profit_factor||0).toFixed(2));
        setRRRColor($('#ew_longProfitFactor'), (stats.direction.Long.profit_factor||0).toFixed(2));
    }
    if(stats.direction.Short.win_rate === 100) {
        $('#ew_shortProfitFactor').text('+∞');
        setRRRColor($('#ew_shortProfitFactor'), '+∞');
    } else {
        $('#ew_shortProfitFactor').text((stats.direction.Short.profit_factor||0).toFixed(2));
        setRRRColor($('#ew_shortProfitFactor'), (stats.direction.Short.profit_factor||0).toFixed(2));
    }
    // 盈亏用红绿色
    let longProfit = stats.direction.Long.total_profit;
    let shortProfit = stats.direction.Short.total_profit;
    let longClass = longProfit > 0 ? 'text-success' : (longProfit < 0 ? 'text-danger' : '');
    let shortClass = shortProfit > 0 ? 'text-success' : (shortProfit < 0 ? 'text-danger' : '');
    $('#ew_longTotalProfit').removeClass('text-success text-danger').addClass(longClass).text(longProfit.toFixed(2));
    $('#ew_shortTotalProfit').removeClass('text-success text-danger').addClass(shortClass).text(shortProfit.toFixed(2));

    // 数学期望
    let longMathExp = stats.direction.Long.win_rate/100 * stats.direction.Long.profit_factor - (1-stats.direction.Long.win_rate/100);
    let shortMathExp = stats.direction.Short.win_rate/100 * stats.direction.Short.profit_factor - (1-stats.direction.Short.win_rate/100);
    if(stats.direction.Long.win_rate === 100) {
        $('#ew_longMathExp').text('+∞');
        setMathExpColor($('#ew_longMathExp'), '+∞');
    } else {
        $('#ew_longMathExp').text(longMathExp.toFixed(2));
        setMathExpColor($('#ew_longMathExp'), longMathExp.toFixed(2));
    }
    if(stats.direction.Short.win_rate === 100) {
        $('#ew_shortMathExp').text('+∞');
        setMathExpColor($('#ew_shortMathExp'), '+∞');
    } else {
        $('#ew_shortMathExp').text(shortMathExp.toFixed(2));
        setMathExpColor($('#ew_shortMathExp'), shortMathExp.toFixed(2));
    }
    
    // Side表格
    $('#ew_leftTrades').text(stats.side.Left.total_trades);
    $('#ew_rightTrades').text(stats.side.Right.total_trades);
    $('#ew_midTrades').text(stats.side.Mid.total_trades);
    $('#ew_leftWinRate').text(stats.side.Left.win_rate.toFixed(2)+'%');
    $('#ew_rightWinRate').text(stats.side.Right.win_rate.toFixed(2)+'%');
    $('#ew_midWinRate').text(stats.side.Mid.win_rate.toFixed(2)+'%');
    // 平均盈利、平均亏损用红绿色
    let leftAvgWin = stats.side.Left.avg_win;
    let rightAvgWin = stats.side.Right.avg_win;
    let midAvgWin = stats.side.Mid.avg_win;
    let leftAvgLoss = stats.side.Left.avg_loss;
    let rightAvgLoss = stats.side.Right.avg_loss;
    let midAvgLoss = stats.side.Mid.avg_loss;
    $('#ew_leftAvgWin').removeClass('text-success text-danger').addClass(leftAvgWin > 0 ? 'text-success' : (leftAvgWin < 0 ? 'text-danger' : '')).text(leftAvgWin.toFixed(2));
    $('#ew_rightAvgWin').removeClass('text-success text-danger').addClass(rightAvgWin > 0 ? 'text-success' : (rightAvgWin < 0 ? 'text-danger' : '')).text(rightAvgWin.toFixed(2));
    $('#ew_midAvgWin').removeClass('text-success text-danger').addClass(midAvgWin > 0 ? 'text-success' : (midAvgWin < 0 ? 'text-danger' : '')).text(midAvgWin.toFixed(2));
    $('#ew_leftAvgLoss').removeClass('text-success text-danger').addClass(leftAvgLoss < 0 ? 'text-danger' : (leftAvgLoss > 0 ? 'text-success' : '')).text(leftAvgLoss.toFixed(2));
    $('#ew_rightAvgLoss').removeClass('text-success text-danger').addClass(rightAvgLoss < 0 ? 'text-danger' : (rightAvgLoss > 0 ? 'text-success' : '')).text(rightAvgLoss.toFixed(2));
    $('#ew_midAvgLoss').removeClass('text-success text-danger').addClass(midAvgLoss < 0 ? 'text-danger' : (midAvgLoss > 0 ? 'text-success' : '')).text(midAvgLoss.toFixed(2));
    // 盈亏比
    if(stats.side.Left.win_rate === 100) {
        $('#ew_leftProfitFactor').text('+∞');
        setRRRColor($('#ew_leftProfitFactor'), '+∞');
    } else {
        $('#ew_leftProfitFactor').text((stats.side.Left.profit_factor||0).toFixed(2));
        setRRRColor($('#ew_leftProfitFactor'), (stats.side.Left.profit_factor||0).toFixed(2));
    }
    if(stats.side.Right.win_rate === 100) {
        $('#ew_rightProfitFactor').text('+∞');
        setRRRColor($('#ew_rightProfitFactor'), '+∞');
    } else {
        $('#ew_rightProfitFactor').text((stats.side.Right.profit_factor||0).toFixed(2));
        setRRRColor($('#ew_rightProfitFactor'), (stats.side.Right.profit_factor||0).toFixed(2));
    }
    if(stats.side.Mid.win_rate === 100) {
        $('#ew_midProfitFactor').text('+∞');
        setRRRColor($('#ew_midProfitFactor'), '+∞');
    } else {
        $('#ew_midProfitFactor').text((stats.side.Mid.profit_factor||0).toFixed(2));
        setRRRColor($('#ew_midProfitFactor'), (stats.side.Mid.profit_factor||0).toFixed(2));
    }
    // 盈亏用红绿色
    let leftProfit = stats.side.Left.total_profit;
    let rightProfit = stats.side.Right.total_profit;
    let midProfit = stats.side.Mid.total_profit;
    let leftClass = leftProfit > 0 ? 'text-success' : (leftProfit < 0 ? 'text-danger' : '');
    let rightClass = rightProfit > 0 ? 'text-success' : (rightProfit < 0 ? 'text-danger' : '');
    let midClass = midProfit > 0 ? 'text-success' : (midProfit < 0 ? 'text-danger' : '');
    $('#ew_leftTotalProfit').removeClass('text-success text-danger').addClass(leftClass).text(leftProfit.toFixed(2));
    $('#ew_rightTotalProfit').removeClass('text-success text-danger').addClass(rightClass).text(rightProfit.toFixed(2));
    $('#ew_midTotalProfit').removeClass('text-success text-danger').addClass(midClass).text(midProfit.toFixed(2));

    // 数学期望
    let leftMathExp = stats.side.Left.win_rate/100 * stats.side.Left.profit_factor - (1-stats.side.Left.win_rate/100);
    let rightMathExp = stats.side.Right.win_rate/100 * stats.side.Right.profit_factor - (1-stats.side.Right.win_rate/100);
    let midMathExp = stats.side.Mid.win_rate/100 * stats.side.Mid.profit_factor - (1-stats.side.Mid.win_rate/100);
    if(stats.side.Left.win_rate === 100) {
        $('#ew_leftMathExp').text('+∞');
        setMathExpColor($('#ew_leftMathExp'), '+∞');
    } else {
        $('#ew_leftMathExp').text(leftMathExp.toFixed(2));
        setMathExpColor($('#ew_leftMathExp'), leftMathExp.toFixed(2));
    }
    if(stats.side.Right.win_rate === 100) {
        $('#ew_rightMathExp').text('+∞');
        setMathExpColor($('#ew_rightMathExp'), '+∞');
    } else {
        $('#ew_rightMathExp').text(rightMathExp.toFixed(2));
        setMathExpColor($('#ew_rightMathExp'), rightMathExp.toFixed(2));
    }
    if(stats.side.Mid.win_rate === 100) {
        $('#ew_midMathExp').text('+∞');
        setMathExpColor($('#ew_midMathExp'), '+∞');
    } else {
        $('#ew_midMathExp').text(midMathExp.toFixed(2));
        setMathExpColor($('#ew_midMathExp'), midMathExp.toFixed(2));
    }
    // 资金曲线
    const canvas = document.getElementById('ew_equityCurveChart');
    canvas.height = 320;
    canvas.style.width = '100%';
    canvas.style.height = '100%';
    if(window.ewEquityChart) window.ewEquityChart.destroy();
    // 只保留日期部分作为横坐标
    const equityLabels = (stats.overall.equity_curve_labels || []).map(label => label.slice(0, 10));
    window.ewEquityChart = new Chart(canvas.getContext('2d'), {
        type: 'line',
        data: {
            labels: equityLabels,
            datasets: [{
                label: '资金曲线',
                data: stats.overall.equity_curve,
                borderColor: 'rgba(75,192,192,1)',
                fill: false,
                spanGaps: true,
                pointRadius: 2
            }]
        },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            layout: { padding: 0 },
            plugins: {
                legend: { display: false },
                zoom: {
                    pan: { enabled: true, mode: 'x' },
                    zoom: {
                        wheel: { enabled: true },
                        drag: { enabled: true },
                        pinch: { enabled: true },
                        mode: 'x'
                    }
                }
            },
            scales: {
                x: {
                    display: true,
                    title: { display: true, text: '日期' },
                    ticks: {
                        autoSkip: true,
                        maxTicksLimit: 8, // 最多显示8个日期
                        callback: function(value, index, values) {
                            // 只显示"YYYY-MM-DD"
                            return this.getLabelForValue(value);
                        }
                    }
                },
                y: { display: true }
            }
        }
    });
    // 最大N笔盈亏
    $('#ew_maxNLossTitle').text(`WORST ${n}`);
    $('#ew_maxNWinTitle').text(`BEST ${n}`);
    let lossHtml = '';
    let worstSum = 0;
    (stats.overall.max_n_loss||[]).forEach(row => {
        const [openDate, openTime] = formatShortTime(row.open_datetime);
        const [closeDate, closeTime] = formatShortTime(row.close_datetime);
        let profit = row.net_profit_value!==undefined?row.net_profit_value:0;
        worstSum += profit;
        let profitColor = profit > 0 ? 'style="color:#28a745;font-weight:bold;"' : (profit < 0 ? 'style="color:#dc3545;font-weight:bold;"' : '');
        let symbol = row.symbol||'';
        if(symbol.length > 3) symbol = symbol.slice(0, -3);
        lossHtml += generateBestWorstTableRow(row, symbol, openDate, openTime, closeDate, closeTime, profitColor);
    });
    // 合计行
    const visibleColumnsCount = columnConfig.best_worst_columns.display_columns.filter(col => col.visible).length;
    lossHtml += `<tr><td colspan="${visibleColumnsCount - 1}" class="text-end fw-bold">合计</td><td class="${worstSum > 0 ? 'text-success' : (worstSum < 0 ? 'text-danger' : '')}">${worstSum > 0 ? '+' : ''}${worstSum.toFixed(2)}</td></tr>`;
    $('#ew_maxNLossBody').html(lossHtml);
    let winHtml = '';
    let bestSum = 0;
    (stats.overall.max_n_win||[]).forEach(row => {
        const [openDate, openTime] = formatShortTime(row.open_datetime);
        const [closeDate, closeTime] = formatShortTime(row.close_datetime);
        let profit = row.net_profit_value!==undefined?row.net_profit_value:0;
        bestSum += profit;
        let profitColor = profit > 0 ? 'style="color:#28a745;font-weight:bold;"' : (profit < 0 ? 'style="color:#dc3545;font-weight:bold;"' : '');
        let symbol = row.symbol||'';
        if(symbol.length > 3) symbol = symbol.slice(0, -3);
        winHtml += generateBestWorstTableRow(row, symbol, openDate, openTime, closeDate, closeTime, profitColor);
    });
    // 合计行
    winHtml += `<tr><td colspan="${visibleColumnsCount - 1}" class="text-end fw-bold">合计</td><td class="${bestSum > 0 ? 'text-success' : (bestSum < 0 ? 'text-danger' : '')}">${bestSum > 0 ? '+' : ''}${bestSum.toFixed(2)}</td></tr>`;
    $('#ew_maxNWinBody').html(winHtml);
    // 周期统计卡片
    let now = new Date();

    // 今日
    let today = new Date(new Date().toLocaleString("en-US", {timeZone: "America/New_York"}));
    let y = today.getFullYear(), m = today.getMonth() + 1, d = today.getDate();
    let dayKey = `${y}-${m}-${d}`;
    let dayStats = aggregatePeriodStats(stats.daily, dayKey, dayKey);
    $('#ew_dayProfit').text(dayStats ? dayStats.total_profit.toFixed() : '0.00');
    setProfitColor($('#ew_dayProfit'), dayStats.total_profit);

    // 本周
    let weekStart = new Date(today);
    weekStart.setDate(today.getDate() - today.getDay()); // 周日为一周第一天
    let weekEnd = new Date(weekStart);
    weekEnd.setDate(weekStart.getDate() + 6);
    let weekStartKey = `${weekStart.getFullYear()}-${weekStart.getMonth()+1}-${weekStart.getDate()}`;
    let weekEndKey = `${weekEnd.getFullYear()}-${weekEnd.getMonth()+1}-${weekEnd.getDate()}`;
    let weekStats = aggregatePeriodStats(stats.daily, weekStartKey, weekEndKey);
    $('#ew_weekProfit').text(weekStats ? weekStats.total_profit.toFixed(0) : '0.00');
    setProfitColor($('#ew_weekProfit'), weekStats.total_profit);
    // 本月
    let monthStartKey = `${y}-${m}-1`;
    let lastDay = new Date(y, m, 0).getDate();
    let monthEndKey = `${y}-${m}-${lastDay}`;
    let monthStats = aggregatePeriodStats(stats.daily, monthStartKey, monthEndKey);
    $('#ew_monthProfit').text(monthStats ? monthStats.total_profit.toFixed(0) : '0.00');
    setProfitColor($('#ew_monthProfit'), monthStats.total_profit);

    // 本年
    let yearStartKey = `${y}-1-1`;
    let yearEndKey = `${y}-12-31`;
    let yearStats = aggregatePeriodStats(stats.daily, yearStartKey, yearEndKey);
    $('#ew_yearProfit').text(yearStats ? yearStats.total_profit.toFixed(0) : '0.00');
    setProfitColor($('#ew_yearProfit'), yearStats.total_profit);


    // Edgewonk风格日历
    let year = parseInt($('#ew_calendarYear').val()) || now.getFullYear();
    let month = parseInt($('#ew_calendarMonth').val()) || (now.getMonth()+1);
    ew_renderProfitCalendar(stats.daily||{}, year, month);
    // 设置Summary时间范围
    let rangeStr = '';
    let rangeVal = $('#ew_dateRange').val();
    if (rangeVal && rangeVal.includes(' to ')) {
        let [start, end] = rangeVal.split(' to ');
        rangeStr = `统计区间：${start} 至 ${end}`;
    } else if (rangeVal) {
        rangeStr = `统计区间：${rangeVal}`;
    } else {
        // 自动获取全部区间
        let labels = stats.overall.equity_curve_labels || [];
        if (labels.length > 0) {
            let first = labels[0].slice(0, 10);
            let last = labels[labels.length-1].slice(0, 10);
            let today = (new Date()).toISOString().slice(0, 10);
            if (last === today) {
                rangeStr = `统计区间：全部（${first} ~ 至今）`;
            } else {
                rangeStr = `统计区间：全部（${first} ~ ${last}）`;
            }
        } else {
            rangeStr = '统计区间：全部';
        }
    }
    document.getElementById('ew_summaryRange').textContent = rangeStr;
    
    // 处理交易品种分析卡片
    ew_updateSymbolsCard(stats);
    
    // 初始化自定义图表过滤器选项
    ew_initCustomChartFilters(stats);
}

// 新增：处理交易品种分析卡片的函数
function ew_updateSymbolsCard(stats) {
    console.log("=== ew_updateSymbolsCard 被调用 ===");
    console.log("stats.symbols:", stats.symbols);
    
    // 检查是否有符号统计数据
    if (!stats.symbols || Object.keys(stats.symbols).length === 0) {
        console.log("❌ 没有符号统计数据，显示空状态");
        // 显示空状态
        $('#ew_symbolCount').text('0');
        $('#ew_bestSymbol').text('--');
        $('#ew_worstSymbol').text('--');
        $('#ew_mainSymbol').text('--');
        $('#ew_symbolsTableBody').html('<tr><td colspan="7" class="text-center text-muted">暂无数据</td></tr>');
        return;
    }
    
    console.log("✅ 有符号统计数据，开始处理");
    
    // 转换为数组并排序
    let symbolsArray = Object.keys(stats.symbols).map(symbol => ({
        symbol: symbol,
        ...stats.symbols[symbol]
    }));
    
    // 按总盈亏排序
    symbolsArray.sort((a, b) => b.total_profit - a.total_profit);
    
    // 更新汇总卡片
    $('#ew_symbolCount').text(symbolsArray.length);
    
    // 最佳品种（总盈亏最高）
    let bestSymbol = symbolsArray[0];
    $('#ew_bestSymbol').text(bestSymbol.symbol);
    
    // 最差品种（总盈亏最低）
    let worstSymbol = symbolsArray[symbolsArray.length - 1];
    $('#ew_worstSymbol').text(worstSymbol.symbol);
    
    // 主要品种（交易次数最多）
    let mainSymbol = symbolsArray.reduce((prev, current) => 
        (prev.total_trades > current.total_trades) ? prev : current
    );
    $('#ew_mainSymbol').text(mainSymbol.symbol);
    
    // 生成表格HTML
    let tableHtml = '';
    symbolsArray.forEach(symbol => {
        let winRate = symbol.total_trades > 0 ? (symbol.winning_trades / symbol.total_trades * 100).toFixed(1) : '0.0';
        let avgProfit = symbol.total_trades > 0 ? (symbol.total_profit / symbol.total_trades).toFixed(2) : '0.00';
        let profitFactor = symbol.avg_loss !== 0 ? (symbol.avg_win / Math.abs(symbol.avg_loss)).toFixed(2) : '+∞';
        let mathExp = symbol.total_trades > 0 ? 
            (symbol.winning_trades / symbol.total_trades * symbol.avg_win - 
             (symbol.total_trades - symbol.winning_trades) / symbol.total_trades * Math.abs(symbol.avg_loss)).toFixed(2) : '0.00';
        
        // 设置颜色类
        let profitClass = symbol.total_profit > 0 ? 'text-success' : 
                         (symbol.total_profit < 0 ? 'text-danger' : '');
        let winRateClass = parseFloat(winRate) >= 50 ? 'text-success' : 'text-danger';
        let profitFactorClass = parseFloat(profitFactor) >= 1.5 ? 'text-success' : 'text-danger';
        let mathExpClass = parseFloat(mathExp) > 0 ? 'text-success' : 'text-danger';
        
        tableHtml += `
            <tr>
                <td class="fw-bold">${symbol.symbol}</td>
                <td class="text-center">${symbol.total_trades}</td>
                <td class="text-center ${winRateClass}">${winRate}%</td>
                <td class="text-center ${profitClass}">${symbol.total_profit.toFixed(2)}</td>
                <td class="text-center ${profitClass}">${avgProfit}</td>
                <td class="text-center ${profitFactorClass}">${profitFactor}</td>
                <td class="text-center ${mathExpClass}">${mathExp}</td>
            </tr>
        `;
    });
    
    $('#ew_symbolsTableBody').html(tableHtml);
}
function ew_fetchStats(n, start, end) {
    console.log("=== ew_fetchStats 被调用 ===");
    console.log("参数:", {n, start, end});
    console.log("当前过滤器:", currentFilters);
    
    let params = { n: n };
    if(start) params.start_date = start;
    if(end) params.end_date = end;
    
    // 添加过滤参数
    if (currentFilters.symbols && currentFilters.symbols.length > 0) {
        params.symbols = currentFilters.symbols;
        console.log("添加品种过滤:", params.symbols);
    }
    if (currentFilters.directions && currentFilters.directions.length > 0) {
        params.directions = currentFilters.directions;
        console.log("添加方向过滤:", params.directions);
    }
    if (currentFilters.trade_types && currentFilters.trade_types.length > 0) {
        params.trade_types = currentFilters.trade_types;
    }
    if (currentFilters.sessions && currentFilters.sessions.length > 0) {
        params.sessions = currentFilters.sessions;
    }
    if (currentFilters.sides && currentFilters.sides.length > 0) {
        params.sides = currentFilters.sides;
        console.log("添加Side过滤:", params.sides);
    }
    if (currentFilters.entry_reasons && currentFilters.entry_reasons.length > 0) {
        params.entry_reasons = currentFilters.entry_reasons;
    }
    if (currentFilters.stop_loss_reasons && currentFilters.stop_loss_reasons.length > 0) {
        params.stop_loss_reasons = currentFilters.stop_loss_reasons;
    }
    if (currentFilters.take_profit_reasons && currentFilters.take_profit_reasons.length > 0) {
        params.take_profit_reasons = currentFilters.take_profit_reasons;
    }
    if (currentFilters.other_exit_reasons && currentFilters.other_exit_reasons.length > 0) {
        params.other_exit_reasons = currentFilters.other_exit_reasons;
    }
    if (currentFilters.profit_status) {
        params.profit_status = currentFilters.profit_status;
    }
    if (currentFilters.profit_min) {
        params.profit_min = currentFilters.profit_min;
    }
    if (currentFilters.profit_max) {
        params.profit_max = currentFilters.profit_max;
    }
    if (currentFilters.duration_min) {
        params.duration_min = currentFilters.duration_min;
    }
    if (currentFilters.duration_max) {
        params.duration_max = currentFilters.duration_max;
    }
    
    console.log("最终发送的参数:", params);
    
    $.ajax({
        url: '/statistics/data',
        type: 'GET',
        data: params,
        traditional: true,  // 使用传统的数组序列化方式
        success: function(stats) {
        console.log("=== API响应接收 ===");
        console.log("响应数据:", stats);
        console.log("过滤信息:", stats.filter_info);
        
        ew_updateStats(stats, n);
        
        // 更新过滤状态显示
        if (stats.filter_info && stats.filter_info.filter_applied) {
            console.log("✅ 显示过滤状态");
            $('#filterStatus').show();
            updateFilterStatusDisplay(stats.filter_info);
        } else {
            console.log("❌ 隐藏过滤状态");
            $('#filterStatus').hide();
        }
        },
        error: function(xhr, status, error) {
        console.error("=== API请求失败 ===");
        console.error("状态:", status);
        console.error("错误:", error);
        console.error("响应:", xhr.responseText);
        }
    });
}
function getWeekNumber(date) {
    const firstDayOfYear = new Date(date.getFullYear(), 0, 1);
    const pastDaysOfYear = (date - firstDayOfYear) / 86400000;
    return Math.ceil((pastDaysOfYear + firstDayOfYear.getDay() + 1) / 7);
}
function formatDateRange(start, end) {
    const formatDate = (date) => {
        return `${date.getMonth() + 1}.${date.getDate()}`;
    };
    return `${formatDate(start)}-${formatDate(end)}`;
}
function ew_renderProfitCalendar(dailyStats, year, month) {
    const view = $('#ew_viewDay').hasClass('active') ? 'day' : 
                $('#ew_viewWeek').hasClass('active') ? 'week' : 'month';
    
    if (view === 'day') {
        // 原有的日视图代码
        let firstDay = new Date(year, month-1, 1);
        let lastDay = new Date(year, month, 0);
        let start = new Date(firstDay);
        start.setDate(1 - firstDay.getDay());
        let end = new Date(lastDay);
        end.setDate(lastDay.getDate() + (6 - lastDay.getDay()));
        let days = [];
        for(let d=new Date(start); d<=end; d.setDate(d.getDate()+1)){
            let y = d.getFullYear(), m = (d.getMonth()+1).toString().padStart(2,'0'), day = d.getDate().toString().padStart(2,'0');
            days.push({date:`${y}-${m}-${day}`, y, m, day, inMonth: d.getMonth()===(month-1)});
        }

        // 添加周一到周日的标志
        let weekHeader = `<div style="display:grid;grid-template-columns:40px repeat(7,1fr);gap:8px;width:100%;margin-bottom:2px;">
        <div></div>
            <div style='text-align:center;color:#888;font-weight:600;'>Sun</div>
            <div style='text-align:center;color:#888;font-weight:600;'>Mon</div>
            <div style='text-align:center;color:#888;font-weight:600;'>Tue</div>
            <div style='text-align:center;color:#888;font-weight:600;'>Wed</div>
            <div style='text-align:center;color:#888;font-weight:600;'>Thu</div>
            <div style='text-align:center;color:#888;font-weight:600;'>Fri</div>
            <div style='text-align:center;color:#888;font-weight:600;'>Sat</div>
        </div>`;

        let html = weekHeader;
        for(let i=0; i<days.length; i+=7){
            let weekDays = days.slice(i, i+7);
            // 取本周第一个日期，算周数
            let weekNum = getWeekNumber(new Date(weekDays[0].date));
            html += `<div style="display:grid;grid-template-columns:40px repeat(7,1fr);gap:8px;width:100%;">`;
            html += `<div style="display:flex;align-items:center;justify-content:center;color:#888;font-weight:600;font-size:13px;">WW${weekNum}</div>`;
    
            //let html = weekHeader + '<div style="display:grid;grid-template-columns:repeat(7,1fr);gap:8px;width:100%;">';
            for(let obj of weekDays){
                //let s = dailyStats[obj.date];
                let s = aggregatePeriodStats(dailyStats, obj.date, obj.date);
                let color = '#f8f9fa', txt='#333', border='1px solid #eee', bg='';
                if(obj.inMonth && s.total_trades>0){
                    if(s.total_profit>0) { color='#e6f9ea'; txt='#28a745'; border='2px solid #b6e2c6'; }
                    else if(s.total_profit<0) { color='#ffeaea'; txt='#dc3545'; border='2px solid #f5b5b5'; }
                    else { color='#f3f3f3'; txt='#888'; border='2px solid #ccc'; }
                } else if(obj.inMonth) {
                    color='#f3f3f3'; txt='#bbb'; border='1px dashed #ccc'; bg='repeating-linear-gradient(135deg,#eee 0 6px,#f3f3f3 6px 12px)';
                } else {
                    color='#f6f6f6'; txt='#ccc'; border='1px dashed #eee'; bg='repeating-linear-gradient(135deg,#eee 0 6px,#f6f6f6 6px 12px)';
                }
                html += `<div class="profit-cell"
                            data-date="${obj.date}"
                            data-total-trades="${s.total_trades}"
                            style="${bg ? `background:${bg};` : `background:${color};`}color:${txt};
                                border-radius:10px;
                                border:${border};
                                padding:0;
                                min-height:65px;
                                aspect-ratio:1.4/1;
                                display:flex;
                                flex-direction:column;
                                align-items:center;
                                justify-content:center;
                                position:relative;
                                box-shadow:0 2px 4px rgba(0,0,0,0.05);
                            ">
                    <div style='font-size:16px;
                            font-weight:700;
                            margin-top:12px;
                            letter-spacing:-0.5px;
                            '>${s.total_trades > 0 ? (s.total_profit>0?'+':'')+s.total_profit.toFixed(2) : 'No Trades'}</div>
                    
                    <div style='position:absolute;left:10px;top:6px;font-size:13px;font-weight:600;opacity:0.8;'>${obj.day}</div>

                    ${obj.inMonth && s && s.total_trades > 0 ? `
                        <div style='font-size:14px;margin-top:2px;opacity:0.7;font-weight:500;'>${obj.inMonth && s ? (s.total_trades===1? '1 trade' : s.total_trades+' trades') : ''}</div>
                        <div style='font-size:13px;margin-top:4px;opacity:0.85;font-weight:500;display:flex;gap:6px;align-items:center;'>
                            <div><span style='color:${(s.trade_based_math_exp>s.math_exp_threshold_level_1)?'#28a745':'#dc3545'};background:${(s.trade_based_math_exp>s.math_exp_threshold_level_1)?'rgba(40,167,69,0.1)':'rgba(220,53,69,0.1)'};padding:1px 4px;border-radius:3px;'>${s.trade_based_win_rate.toFixed(1)}%</span></div>
                            <div><span style='color:${(s.trade_based_math_exp>s.math_exp_threshold_level_1)?'#28a745':'#dc3545'};background:${(s.trade_based_math_exp>s.math_exp_threshold_level_1)?'rgba(40,167,69,0.1)':'rgba(220,53,69,0.1)'};padding:1px 4px;border-radius:3px;'>${s.trade_based_rrr == Infinity ? '+∞' : s.trade_based_rrr.toFixed(1)}</span></div>
                            <div><span style='color:${(s.trade_based_math_exp>s.math_exp_threshold_level_1)?'#28a745':'#dc3545'};background:${(s.trade_based_math_exp>s.math_exp_threshold_level_1)?'rgba(40,167,69,0.1)':'rgba(220,53,69,0.1)'};padding:1px 4px;border-radius:3px;'>${s.trade_based_math_exp == Infinity ? '+∞' : s.trade_based_math_exp.toFixed(2)}</span></div>
                        </div>
                    ` : ''}
                </div>`;
            }
            html += '</div>';
        }
        document.getElementById('ew_profitCalendar').innerHTML = html;
    } else if (view === 'week') {
        // 周视图：显示整个季度所有周
        // 计算季度
        const quarter = Math.floor((month - 1) / 3);
        const quarterStartMonth = quarter * 3 + 1;
        const quarterEndMonth = (quarter + 1) * 3;
        const quarterStart = new Date(year, quarterStartMonth - 1, 1);
        const quarterEnd = new Date(year, quarterEndMonth, 0); // 季度最后一天
        // 找到季度首周的周日
        let firstWeekStart = new Date(quarterStart);
        firstWeekStart.setDate(firstWeekStart.getDate() - firstWeekStart.getDay());
        // 找到季度末周的周六
        let lastWeekEnd = new Date(quarterEnd);
        lastWeekEnd.setDate(lastWeekEnd.getDate() + (6 - lastWeekEnd.getDay()));
        // 遍历所有周
        let weeks = [];
        for(let d = new Date(firstWeekStart); d <= lastWeekEnd; d.setDate(d.getDate() + 7)) {
            let weekStart = new Date(d);
            let weekEnd = new Date(d);
            weekEnd.setDate(weekStart.getDate() + 6);
            weeks.push({
                start: new Date(weekStart),
                end: new Date(weekEnd),
                weekNumber: getWeekNumber(weekStart)
            });
        }
        // repeat(4,1fr)表示创建一个4列的网格布局，每列宽度相等(各占1份)
        let html = '<div style="display:grid;grid-template-columns:repeat(4,1fr);gap:6px;width:100%;">';
        for(let week of weeks) {
            let weekStats = aggregatePeriodStats(dailyStats, week.start, week.end);
            
            // 统一No Trades风格
            let color = '#f8f9fa', txt='#333', border='1px solid #eee', bg='';
            if(weekStats.total_trades > 0) {
                if(weekStats.total_profit > 0) { color='#e6f9ea'; txt='#28a745'; border='2px solid #b6e2c6'; }
                else if(weekStats.total_profit < 0) { color='#ffeaea'; txt='#dc3545'; border='2px solid #f5b5b5'; }
                else { color='#f3f3f3'; txt='#888'; border='2px solid #ccc'; }
            } else {
                color='#f3f3f3'; txt='#bbb'; border='1px dashed #ccc'; bg='repeating-linear-gradient(135deg,#eee 0 6px,#f8f9fa 6px 12px)';
            }
            html += `<div class="profit-cell" 
                data-week="${week.start.getFullYear()}-${(week.start.getMonth()+1).toString().padStart(2,'0')}-${week.start.getDate().toString().padStart(2,'0')}" 
                data-week-end="${week.end.getFullYear()}-${(week.end.getMonth()+1).toString().padStart(2,'0')}-${week.end.getDate().toString().padStart(2,'0')}" 
                data-total-trades="${weekStats.total_trades}"
                style="background:${color};
                        color:${txt};
                        border-radius:8px;border:${border}
                        padding:0;
                        min-height:55px;
                        aspect-ratio:2/1;
                        display:flex;
                        flex-direction:column;
                        align-items:center;
                        justify-content:center;
                        position:relative;
                        box-shadow:0 2px 4px rgba(0,0,0,0.05);
                        ${bg?`background:${bg};`:''}">
                <div style='display:flex;justify-content:space-between;position:absolute;top:4px;left:8px;right:8px;font-size:14px;font-weight:600;opacity:0.8;color:#888;'>
                    <div>WW${week.weekNumber.toString().padStart(2,'0')}</div>
                    <div>${formatDateRange(week.start, week.end)}</div>
                </div>
                <div style='font-size:16px;font-weight:700;margin-top:12px;letter-spacing:-0.5px;'>${weekStats.total_trades > 0 ? (weekStats.total_profit>0?'+':'')+weekStats.total_profit.toFixed(2) : 'No Trades'}</div>

                 ${weekStats.total_trades > 0 ? `
                <div style='font-size:11px;margin-top:2px;opacity:0.7;font-weight:500;'>${weekStats.total_trades} trades</div>
                <div class="d-flex justify-content-between mt-2">
                    <div style="text-align:center; margin-right:12px;">
                        <div style="font-size:14px;color:#888;">trade-based</div>
                        <div style="font-size:14px;">
                            <div><span style='color:${(weekStats.trade_based_math_exp>weekStats.math_exp_threshold_level_1) ?'#28a745':'#dc3545'};background:${(weekStats.trade_based_math_exp>weekStats.math_exp_threshold_level_1)?'rgba(40,167,69,0.1)':'rgba(220,53,69,0.1)'};padding:1px 4px;border-radius:3px;'>${weekStats.trade_based_win_rate.toFixed(1)}%</span></div>
                            <div><span style='color:${(weekStats.trade_based_math_exp>weekStats.math_exp_threshold_level_1) ?'#28a745':'#dc3545'};background:${(weekStats.trade_based_math_exp>weekStats.math_exp_threshold_level_1)?'rgba(40,167,69,0.1)':'rgba(220,53,69,0.1)'};padding:1px 4px;border-radius:3px;'>${weekStats.trade_based_rrr == Infinity ? '+∞' : weekStats.trade_based_rrr.toFixed(1)}</span></div>
                            <div><span style='color:${(weekStats.trade_based_math_exp>weekStats.math_exp_threshold_level_1) ?'#28a745':'#dc3545'};background:${(weekStats.trade_based_math_exp>weekStats.math_exp_threshold_level_1)?'rgba(40,167,69,0.1)':'rgba(220,53,69,0.1)'};padding:1px 4px;border-radius:3px;'>${weekStats.trade_based_math_exp == Infinity ? '+∞' : weekStats.trade_based_math_exp.toFixed(2)}</span></div>
                        </div>
                    </div>
                    <div style="text-align:center; margin-left:12px;">
                        <div style="font-size:14px;color:#888;">day-based</div>
                        <div style="font-size:14px;">
                            <div><span style='color:${(weekStats.day_based_math_exp>weekStats.math_exp_threshold_level_1) ?'#28a745':'#dc3545'};background:${(weekStats.day_based_math_exp>weekStats.math_exp_threshold_level_1)?'rgba(40,167,69,0.1)':'rgba(220,53,69,0.1)'};padding:1px 4px;border-radius:3px;'>${weekStats.day_based_win_rate.toFixed(1)}%</span></div>
                            <div><span style='color:${(weekStats.day_based_math_exp>weekStats.math_exp_threshold_level_1) ?'#28a745':'#dc3545'};background:${(weekStats.day_based_math_exp>weekStats.math_exp_threshold_level_1)?'rgba(40,167,69,0.1)':'rgba(220,53,69,0.1)'};padding:1px 4px;border-radius:3px;'>${weekStats.day_based_rrr == Infinity ? '+∞' : weekStats.day_based_rrr.toFixed(1)}</span></div>
                            <div><span style='color:${(weekStats.day_based_math_exp>weekStats.math_exp_threshold_level_1) ?'#28a745':'#dc3545'};background:${(weekStats.day_based_math_exp>weekStats.math_exp_threshold_level_1)?'rgba(40,167,69,0.1)':'rgba(220,53,69,0.1)'};padding:1px 4px;border-radius:3px;'>${weekStats.day_based_math_exp == Infinity ? '+∞' : weekStats.day_based_math_exp.toFixed(2)}</span></div>
                        </div>
                    </div>
                </div>
                ` : ''}
            </div>`;
        }
        html += '</div>';
        document.getElementById('ew_profitCalendar').innerHTML = html;
        // 设置季度标签
        const quarterNames = ['Q1', 'Q2', 'Q3', 'Q4'];
        $('#ew_calendarLabel').text(`${quarterNames[quarter]} ${year}`);
    } else {
        // 月视图：显示当年1-12月所有月份
        let months = [];
        for(let m=1; m<=12; m++) {
            let monthStart = new Date(year, m-1, 1);
            let monthEnd = new Date(year, m, 0);
            let monthStats = aggregatePeriodStats(dailyStats, monthStart, monthEnd);
            months.push({
                month: m,
                stats: monthStats
            });
        }
        let html = '<div style="display:grid;grid-template-columns:repeat(4,1fr);gap:6px;width:100%;">';
        for(let obj of months) {
            let s = obj.stats;
            let color = '#f8f9fa', txt='#333', border='1px solid #eee', bg='';
            if(s.total_trades > 0) {
                if(s.total_profit > 0) { color='#e6f9ea'; txt='#28a745'; border='2px solid #b6e2c6'; }
                else if(s.total_profit < 0) { color='#ffeaea'; txt='#dc3545'; border='2px solid #f5b5b5'; }
                else { color='#f3f3f3'; txt='#888'; border='2px solid #ccc'; }
            } else {
                color='#f3f3f3'; txt='#bbb'; border='1px dashed #ccc'; bg='repeating-linear-gradient(135deg,#eee 0 6px,#f8f9fa 6px 12px)';
            }
            html += `<div class="profit-cell" data-month="${year}-${obj.month.toString().padStart(2,'0')}" data-total-trades="${s.total_trades}" style="color:${txt};border-radius:8px;border:${border};padding:0;min-height:55px;aspect-ratio:2/1;display:flex;flex-direction:column;align-items:center;justify-content:center;position:relative;${bg ? `background:${bg};` : `background:${color};`}box-shadow:0 2px 4px rgba(0,0,0,0.05);">
                <div style='position:absolute;left:8px;top:4px;font-size:11px;font-weight:600;opacity:0.8;'>${obj.month}月</div>
                <div style='font-size:16px;font-weight:700;margin-top:12px;letter-spacing:-0.5px;'>${s.total_trades > 0 ? (s.total_profit>0?'+':'')+s.total_profit.toFixed(2) : 'No Trades'}</div>

                ${s.total_trades > 0 ? `
                <div style='font-size:11px;margin-top:2px;opacity:0.7;font-weight:500;'>${s.total_trades} trades</div>
                <div class="d-flex justify-content-between mt-2">
                    <div style="text-align:center; margin-right:12px;">
                        <div style="font-size:14px;color:#888;">trade-based</div>
                        <div style="font-size:14px;">
                            <div><span style='color:${(s.trade_based_math_exp>s.math_exp_threshold_level_1)?'#28a745':'#dc3545'};background:${(s.trade_based_math_exp>s.math_exp_threshold_level_1)?'rgba(40,167,69,0.1)':'rgba(220,53,69,0.1)'};padding:1px 4px;border-radius:3px;'>${s.trade_based_win_rate.toFixed(1)}%</span></div>
                            <div><span style='color:${(s.trade_based_math_exp>s.math_exp_threshold_level_1)?'#28a745':'#dc3545'};background:${(s.trade_based_math_exp>s.math_exp_threshold_level_1)?'rgba(40,167,69,0.1)':'rgba(220,53,69,0.1)'};padding:1px 4px;border-radius:3px;'>${s.trade_based_rrr == Infinity ? '+∞' : s.trade_based_rrr.toFixed(1)}</span></div>
                            <div><span style='color:${(s.trade_based_math_exp>s.math_exp_threshold_level_1)?'#28a745':'#dc3545'};background:${(s.trade_based_math_exp>s.math_exp_threshold_level_1)?'rgba(40,167,69,0.1)':'rgba(220,53,69,0.1)'};padding:1px 4px;border-radius:3px;'>${s.trade_based_math_exp == Infinity ? '+∞' : s.trade_based_math_exp.toFixed(2)}</span></div>
                        </div>
                    </div>
                    <div style="text-align:center; margin-right:12px;">
                        <div style="font-size:14px;color:#888;">day-based</div>
                        <div style="font-size:14px;">
                            <div><span style='color:${(s.trade_based_math_exp>s.math_exp_threshold_level_1)?'#28a745':'#dc3545'};background:${(s.trade_based_math_exp>s.math_exp_threshold_level_1)?'rgba(40,167,69,0.1)':'rgba(220,53,69,0.1)'};padding:1px 4px;border-radius:3px;'>${s.day_based_win_rate.toFixed(1)}%</span></div>
                            <div><span style='color:${(s.trade_based_math_exp>s.math_exp_threshold_level_1)?'#28a745':'#dc3545'};background:${(s.trade_based_math_exp>s.math_exp_threshold_level_1)?'rgba(40,167,69,0.1)':'rgba(220,53,69,0.1)'};padding:1px 4px;border-radius:3px;'>${s.day_based_rrr == Infinity ? '+∞' : s.day_based_rrr.toFixed(1)}</span></div>
                            <div><span style='color:${(s.trade_based_math_exp>s.math_exp_threshold_level_1)?'#28a745':'#dc3545'};background:${(s.trade_based_math_exp>s.math_exp_threshold_level_1)?'rgba(40,167,69,0.1)':'rgba(220,53,69,0.1)'};padding:1px 4px;border-radius:3px;'>${s.day_based_math_exp == Infinity ? '+∞' : s.day_based_math_exp.toFixed(2)}</span></div>
                        </div>
                    </div>
                </div>
                ` : ''}                
            </div>`;
        }
        html += '</div>';
        document.getElementById('ew_profitCalendar').innerHTML = html;
        // 设置年份标签
        $('#ew_calendarLabel').text(`${year}`);
    }
    
    // 设置月份标签（统一放到函数最后，避免被覆盖）
    if (view === 'day') {
        const monthNames = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
        $('#ew_calendarLabel').text(`${monthNames[month-1]} ${year}`);
    } else if (view === 'week') {
        const quarterNames = ['Q1', 'Q2', 'Q3', 'Q4'];
        const quarter = Math.floor((month - 1) / 3);
        $('#ew_calendarLabel').text(`${quarterNames[quarter]} ${year}`);
    } else if (view === 'month') {
        $('#ew_calendarLabel').text(`${year}`);
    }
}
function syncEquityCardHeight() {
    // 获取左侧Summary和Session统计两卡片的总高度
    var summary = $('.card-header.bg-success:contains("Summary")').parent()[0];
    var session = $('.card-header.bg-success:contains("Session统计")').parent()[0];
    if (summary && session) {
        var total = summary.offsetHeight + session.offsetHeight + 8; // 8为gap
        var equityCard = $('.card-header.bg-success:contains("资金曲线")').parent()[0];
        if (equityCard) {
            equityCard.style.height = total + 'px';
        }
    }
}
window.addEventListener('load', syncEquityCardHeight);
window.addEventListener('resize', syncEquityCardHeight);
$(document).ready(function() {
    // 加载列配置
    loadColumnConfig();
    
    // 初始化过滤器
    initializeFilters();
    
    // 初始化快速配置按钮
    ew_loadQuickConfigs();
    
    // 初始化多图表系统
    ew_initMultiChartSystem();
    
    // 配置管理按钮事件
    $('#statisticsConfigBtn').click(function() {
        showStatisticsConfigModal();
    });
    
    // 保存配置按钮事件
    $('#saveStatisticsConfig').click(function() {
        saveStatisticsConfig();
    });
    
    let n = parseInt($('#ew_maxN').val()) || 5;
    ew_fetchStats(n);
    $('#ew_refreshStats').click(function() {
        let n = parseInt($('#ew_maxN').val()) || 5;
        ew_fetchStats(n);
    });
    
    // 过滤器相关事件
    $('#ew_toggleFilter').click(function() {
        $('#filterPanel').slideToggle();
    });
    
    $('#applyFilter').click(function() {
        applyFilters();
    });
    
    $('#clearFilter').click(function() {
        clearFilters();
    });
    
    $('#showFilterDetails').click(function() {
        showFilterDetails();
    });
    
    // 初始化年份和月份选择器
    let now = new Date();
    let y = now.getFullYear();
    let m = now.getMonth()+1;
    let yearSel = $('#ew_calendarYear');
    let monthSel = $('#ew_calendarMonth');
    for(let i=y-5;i<=y+1;i++) yearSel.append(`<option value="${i}"${i===y?' selected':''}>${i}</option>`);
    for(let i=1;i<=12;i++) monthSel.append(`<option value="${i}"${i===m?' selected':''}>${i.toString().padStart(2,'0')}</option>`);
    yearSel.change(function(){ ew_fetchStats(parseInt($('#ew_maxN').val())||5); });
    monthSel.change(function(){ ew_fetchStats(parseInt($('#ew_maxN').val())||5); });
    // 视图切换按钮
    $('#ew_viewDay, #ew_viewWeek, #ew_viewMonth').click(function() {
        $('#ew_viewDay, #ew_viewWeek, #ew_viewMonth').removeClass('active');
        $(this).addClass('active');
        let year = parseInt($('#ew_calendarYear').val()) || new Date().getFullYear();
        let month = parseInt($('#ew_calendarMonth').val()) || (new Date().getMonth()+1);
        if (window.ewStats) {
            ew_renderProfitCalendar(window.ewStats.daily||{}, year, month);
        }
    });

    // 周期切换按钮
    let curYear = new Date().getFullYear();
    let curMonth = new Date().getMonth() + 1;
    
    function setPeriod(y, m) {
        curYear = y;
        curMonth = m;
        if (window.ewStats) {
            ew_renderProfitCalendar(window.ewStats.daily||{}, y, m);
        }
    }
    
    // ===================== 日历切换按钮逻辑修正 =====================
    // 只在本作用域内维护当前显示的年/月
    function getCurrentCalendarYearMonth() {
        // 解析 #ew_calendarLabel 的内容
        const label = $('#ew_calendarLabel').text();
        let year = new Date().getFullYear();
        let month = new Date().getMonth() + 1;
        // 日/月视图: "May 2025" 或 "2025"
        if (/\d{4}/.test(label)) {
            year = parseInt(label.match(/\d{4}/)[0]);
        }
        // 日/月视图: "May 2025"
        if (/([A-Za-z]+) (\d{4})/.test(label)) {
            const m = label.match(/([A-Za-z]+) (\d{4})/);
            const monthNames = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
            month = monthNames.indexOf(m[1]) + 1;
        }
        // 周视图: "Q1 2025"，推算季度首月
        if (/Q(\d) (\d{4})/.test(label)) {
            const m = label.match(/Q(\d) (\d{4})/);
            year = parseInt(m[2]);
            month = (parseInt(m[1]) - 1) * 3 + 1;
        }
        return {year, month};
    }

    $('#ew_prevPeriod').off('click').on('click', function(){
        const view = $('#ew_viewDay').hasClass('active') ? 'day' : $('#ew_viewWeek').hasClass('active') ? 'week' : 'month';
        let {year, month} = getCurrentCalendarYearMonth();
        if (view === 'week') {
            // 上一季度
            let quarter = Math.floor((month - 1) / 3);
            if (quarter === 0) {
                year--;
                month = 10;
            } else {
                month = (quarter - 1) * 3 + 1;
            }
            month = [1,4,7,10][Math.floor((month-1)/3)];
        } else if (view === 'month') {
            // 上一年
            year--;
        } else {
            // 上一月
            month--;
            if (month < 1) {
                month = 12;
                year--;
            }
        }
        ew_renderProfitCalendar(window.ewStats.daily||{}, year, month);
    });

    $('#ew_nextPeriod').off('click').on('click', function(){
        const view = $('#ew_viewDay').hasClass('active') ? 'day' : $('#ew_viewWeek').hasClass('active') ? 'week' : 'month';
        let {year, month} = getCurrentCalendarYearMonth();
        if (view === 'week') {
            // 下一季度
            let quarter = Math.floor((month - 1) / 3);
            if (quarter === 3) {
                year++;
                month = 1;
            } else {
                month = (quarter + 1) * 3 + 1;
            }
            month = [1,4,7,10][Math.floor((month-1)/3)];
        } else if (view === 'month') {
            // 下一年
            year++;
        } else {
            // 下一月
            month++;
            if (month > 12) {
                month = 1;
                year++;
            }
        }
        ew_renderProfitCalendar(window.ewStats.daily||{}, year, month);
    });

    // 切换视图时也同步当前显示周期
    $('#ew_viewDay, #ew_viewWeek, #ew_viewMonth').off('click').on('click', function() {
        $('#ew_viewDay, #ew_viewWeek, #ew_viewMonth').removeClass('active');
        $(this).addClass('active');
        let {year, month} = getCurrentCalendarYearMonth();
        ew_renderProfitCalendar(window.ewStats.daily||{}, year, month);
    });

    $('#ew_prevPeriod').click(function(){
        if ($('#ew_viewWeek').hasClass('active')) {
            // 季度切换
            let quarter = Math.floor((curMonth - 1) / 3);
            if (quarter === 0) {
                curYear--;
                curMonth = 10; // Q4
            } else {
                curMonth = (quarter - 1) * 3 + 1; // 上一个季度的第一个月
            }
            // 强制curMonth为1/4/7/10
            curMonth = [1,4,7,10][Math.floor((curMonth-1)/3)];
        } else if ($('#ew_viewMonth').hasClass('active')) {
            // 年切换
            curYear--;
        } else {
            // 月份切换
            curMonth--;
            if (curMonth < 1) {
                curMonth = 12;
                curYear--;
            }
        }
        setPeriod(curYear, curMonth);
    });
    
    $('#ew_nextPeriod').click(function(){
        if ($('#ew_viewWeek').hasClass('active')) {
            // 季度切换
            let quarter = Math.floor((curMonth - 1) / 3);
            if (quarter === 3) {
                curYear++;
                curMonth = 1; // Q1
            } else {
                curMonth = (quarter + 1) * 3 + 1; // 下一个季度的第一个月
            }
            // 强制curMonth为1/4/7/10
            curMonth = [1,4,7,10][Math.floor((curMonth-1)/3)];
        } else if ($('#ew_viewMonth').hasClass('active')) {
            // 年切换
            curYear++;
        } else {
            // 月份切换
            curMonth++;
            if (curMonth > 12) {
                curMonth = 1;
                curYear++;
            }
        }
        setPeriod(curYear, curMonth);
    });
    // 初始化flatpickr区间选择
    function formatDateLocal(date) {
        const y = date.getFullYear();
        const m = (date.getMonth() + 1).toString().padStart(2, '0');
        const d = date.getDate().toString().padStart(2, '0');
        return `${y}-${m}-${d}`;
    }
    flatpickr("#ew_dateRange", {
        mode: "range",
        dateFormat: "Y-m-d",
        locale: "zh",
        onClose: function(selectedDates, dateStr, instance) {
            let n = parseInt($('#ew_maxN').val()) || 5;
            let start = selectedDates[0] ? formatDateLocal(selectedDates[0]) : '';
            let end = selectedDates[1] ? formatDateLocal(selectedDates[1]) : '';
            ew_fetchStats(n, start, end);
        }
    });

    // 添加"全部"按钮点击事件
    $('#ew_selectAll').click(function() {
        // 清空日期选择器的值
        $('#ew_dateRange').val('');
        // 获取统计数据
        let n = parseInt($('#ew_maxN').val()) || 5;
        ew_fetchStats(n);
    });
    
    // 过滤器管理相关事件
    $('#saveFilter').click(function() {
        saveCurrentFilter();
    });
    
    $('#manageFilters').click(function() {
        showManageFiltersModal();
    });
    
    // 初始化已保存的过滤器
    loadSavedFilters();
});

function aggregatePeriodStats(dailyStats, start, end) {
    // 调试开关
    const DEBUG = false;
    
    const log = (...args) => {
        if (DEBUG) console.log(...args);
    };

    const warn = (...args) => {
        if (DEBUG) console.warn(...args);
    };

    const error = (...args) => {
        if (DEBUG) console.error(...args);
    };

    log('开始聚合统计, 参数:', {
        start: start,
        end: end,
        dailyStats: dailyStats
    });

    // 参数检查
    if (!start || !end || !dailyStats) {
        warn('参数无效, 返回空统计', {start, end, dailyStats});
        return null;
    }

    let stats = {
        total_profit: 0,
        total_trades: 0,
        day_based_win_rate: 0,
        day_based_rrr: 0,
        day_based_math_exp: 0,
        trade_based_win_rate: 0,
        trade_based_rrr: 0,
        trade_based_math_exp: 0,
        math_exp_threshold_level_1: 0,
        math_exp_threshold_level_2: 0.2,
        math_exp_threshold_level_3: 0.5
    };

    let totalTrades = 0;
    let totalProfit = 0;

    // day based statistics
    let winDays = 0, lossDays = 0;
    let dayWinProfit = 0, dayLossProfit = 0;

    // trade based statistics
    let winTrades = 0, lossTrades = 0;
    let winProfit = 0, lossProfit = 0;

    try {
        let cur = new Date(start);
        let endDate = new Date(end);
        log('开始遍历日期:', {
            startDate: cur.toLocaleDateString(),
            endDate: endDate.toLocaleDateString()
        });

        while(cur <= endDate) {
            let key = `${cur.getFullYear()}-${(cur.getMonth()+1).toString().padStart(2,'0')}-${cur.getDate().toString().padStart(2,'0')}`;
            let day = dailyStats[key];
            log(`处理日期 ${key}:`, day);

            if(day) {
                // general data
                totalTrades += day.total_trades || 0;
                totalProfit += day.total_profit || 0;

                // day based data collection
                if (day.total_profit > 0) {
                    winDays++;
                    dayWinProfit += day.total_profit;
                    log(`盈利日: profit=${day.total_profit}, winDays=${winDays}, dayWinProfit=${dayWinProfit}`);
                } else if (day.total_profit < 0) {
                    lossDays++;
                    dayLossProfit += Math.abs(day.total_profit);
                    log(`亏损日: profit=${day.total_profit}, lossDays=${lossDays}, dayLossProfit=${dayLossProfit}`);
                }

                // trade based data collection
                winTrades += day.winning_trades || 0;
                lossTrades += day.losing_trades || 0;
                winProfit += (day.avg_win || 0) * (day.winning_trades || 0);
                lossProfit += (day.avg_loss || 0) * (day.losing_trades || 0);
                log('交易统计:', {
                    winningTrades: day.winning_trades,
                    losingTrades: day.losing_trades,
                    avgWin: day.avg_win,
                    avgLoss: day.avg_loss,
                    累计胜: winTrades,
                    累计负: lossTrades,
                    累计盈: winProfit,
                    累计亏: lossProfit
                });
            }
            cur.setDate(cur.getDate() + 1);
        }

        // 计算统计指标
        stats.total_profit = totalProfit;
        stats.total_trades = totalTrades;

        // day based statistics
        const totalDaysCount = winDays + lossDays;
        stats.day_based_win_rate = totalDaysCount > 0 ? (winDays / totalDaysCount * 100) : 0;
        stats.day_based_rrr = winDays == 0 ? 0 : lossDays == 0 ? Infinity : lossProfit == 0 ? Infinity : (dayWinProfit/winDays) / Math.abs(dayLossProfit/lossDays);
        stats.day_based_math_exp = stats.day_based_win_rate * stats.day_based_rrr/100 - (1-stats.day_based_win_rate/100);

        // trade based statistics
        const totalTradesCount = winTrades + lossTrades;
        stats.trade_based_win_rate = totalTradesCount > 0 ? (winTrades / totalTradesCount * 100) : 0;
        stats.trade_based_rrr = winTrades == 0 ? 0 : lossTrades == 0 ? Infinity : lossProfit == 0 ? Infinity : (winProfit/winTrades) / Math.abs(lossProfit/lossTrades);
        stats.trade_based_math_exp = stats.trade_based_win_rate * stats.trade_based_rrr/100 - (1-stats.trade_based_win_rate/100);

        log('统计结果:', {
            总交易天数: totalDaysCount,
            盈利天数: winDays,
            亏损天数: lossDays,
            日胜率: stats.day_based_win_rate,
            日盈亏比: stats.day_based_rrr,
            日数学期望: stats.day_based_math_exp,
            总交易次数: totalTradesCount,
            盈利次数: winTrades,
            亏损次数: lossTrades,
            交易胜率: stats.trade_based_win_rate,
            交易盈亏比: stats.trade_based_rrr,
            交易数学期望: stats.trade_based_math_exp
        });

        return stats;

    } catch(err) {
        error('聚合统计出错:', err);
        return null;
    }
}

function formatShortTime(str) {
    if (!str) return ['', ''];
    const d = new Date(str);
    if (isNaN(d)) return [str, ''];
    return [
        `${(d.getMonth()+1).toString().padStart(2,'0')}-${d.getDate().toString().padStart(2,'0')}`,
        `${d.getHours().toString().padStart(2,'0')}:${d.getMinutes().toString().padStart(2,'0')}`
    ];
}
// // 卡片最小化/展开
// $(document).on('click', '.dashboard-toggle-btn', function() {
//     var target = $(this).data('target');
//     $(target).slideToggle(150);
//     var icon = $(this).text();
//     $(this).text(icon === '-' ? '+' : '-');
// });
// 拖拽排序+宽度记忆
function saveDashboardLayout() {
    let layout = [];
    document.querySelectorAll('.dashboard-grid .dashboard-card').forEach(card => {
        layout.push({
            id: card.getAttribute('data-id'),
            span: card.getAttribute('data-span')
        });
    });
    localStorage.setItem('dashboardLayout', JSON.stringify(layout));
}
function loadDashboardLayout() {
    let layout = JSON.parse(localStorage.getItem('dashboardLayout')||'[]');
    if(layout.length) {
        let grid = document.querySelector('.dashboard-grid');
        let cards = {};
        grid.querySelectorAll('.dashboard-card').forEach(card => {
            cards[card.getAttribute('data-id')] = card;
        });
        
        // 检查是否有新卡片（不在保存布局中的）
        let hasNewCards = Object.keys(cards).some(cardId => 
            !layout.find(item => item.id === cardId)
        );
        
        if(hasNewCards) {
            console.log('检测到新卡片，重新初始化布局');
            localStorage.removeItem('dashboardLayout');
            return; // 让卡片保持HTML中的默认顺序
        }
        
        // 如果没有新卡片，按保存的布局排列
        grid.innerHTML = '';
        layout.forEach(item => {
            if(cards[item.id]) {
                cards[item.id].setAttribute('data-span', item.span);
                cards[item.id].style.gridColumn = 'span '+item.span;
                grid.appendChild(cards[item.id]);
            }
        });
    }
}
document.addEventListener('DOMContentLoaded', function(){
    loadDashboardLayout();
    Sortable.create(document.querySelector('.dashboard-grid'), {
        animation: 150,
        handle: '.card-header',
        draggable: '.dashboard-card',
        ghostClass: 'sortable-ghost',
        onEnd: saveDashboardLayout
    });
    // 拖拽右侧手柄调整宽度
    let dragging = false, startX = 0, startSpan = 0, card = null;
    document.querySelectorAll('.resize-handle').forEach(handle => {
        handle.addEventListener('mousedown', function(e){
            dragging = true;
            card = handle.parentElement;
            startX = e.clientX;
            startSpan = parseInt(card.getAttribute('data-span'))||1;
            document.body.style.userSelect = 'none';
        });
    });
    document.addEventListener('mousemove', function(e){
        if(dragging && card){
            let dx = e.clientX - startX;
            let grid = document.querySelector('.dashboard-grid');
            let gridWidth = grid.offsetWidth;
            let colWidth = gridWidth/4;
            let newSpan = Math.min(4, Math.max(1, Math.round(startSpan + dx/colWidth)));
            card.setAttribute('data-span', newSpan);
            card.style.gridColumn = 'span '+newSpan;
        }
    });
    document.addEventListener('mouseup', function(){
        if(dragging && card){
            saveDashboardLayout();
        }
        dragging = false; card = null;
        document.body.style.userSelect = '';
    });
});
// 确保tooltip div存在
if (!document.getElementById('profitTooltip')) {
  const tooltip = document.createElement('div');
  tooltip.id = 'profitTooltip';
  tooltip.style = 'position:absolute;z-index:9999;display:none;min-width:260px;max-width:480px;background:#fff;border-radius:12px;box-shadow:0 4px 16px rgba(0,0,0,0.12);padding:18px 20px;font-size:15px;pointer-events:none;';
  document.body.appendChild(tooltip);
}
// 悬停tooltip逻辑，支持日、周、月
$(document).on('mouseenter', '.profit-cell', function(e){
    let html = '';
    let stats = null;
    let label = '';
    let start, end;
    if ($(this).data('date')) {
        // 日视图
        const date = $(this).data('date');
        //stats = window.ewStats?.daily?.[date];   
        label = date;
        start = end = date;

    } else if ($(this).data('week')) {
        // 周视图
        start = $(this).data('week');
        end = $(this).data('week-end');
        label = `${start} ~ ${end}`;
    } else if ($(this).data('month')) {
        // 月视图
        const month = $(this).data('month');
        start = month + '-01';
        let [y, m] = month.split('-');
        let daysInMonth = new Date(y, m, 0).getDate();
        end = month + '-' + daysInMonth.toString().padStart(2, '0');
        label = `${month}`;
    }
    stats = aggregatePeriodStats(window.ewStats.daily, start, end);    


    // 打印stats的详细内容
    console.log('Period Stats:', {
        date: label,
        start: start,
        end: end,
        stats: {
            total_profit: stats?.total_profit,
            total_trades: stats?.total_trades,
            trade_based_win_rate: stats?.trade_based_win_rate,
            trade_based_rrr: stats?.trade_based_rrr,
            trade_based_math_exp: stats?.trade_based_math_exp,
            day_based_win_rate: stats?.day_based_win_rate, 
            day_based_rrr: stats?.day_based_rrr,
            day_based_math_exp: stats?.day_based_math_exp,
            raw: stats
        }
    });


    if (!stats) {
        html = `<div style="font-size:13px;color:#888;">${label}</div><div style="font-size:18px;color:#888;margin:10px 0;">无交易数据</div>`;
        $('#profitTooltip').html(html).css({
          left: e.pageX + 16,
          top: e.pageY - 10,
          display: 'block'
        });
        return;
    }
    html = `
      <div style="font-size:13px;color:#888;">${label}</div>
      <div style="font-size:28px;font-weight:700;color:${stats.total_profit>0?'#28a745':(stats.total_profit<0?'#dc3545':'#333')};margin:8px 0 4px 0;">
        ${stats.total_profit>0?'+':''}${stats.total_profit != null ? stats.total_profit.toFixed(2) : '0.00'}
      </div>
      <div style="font-size:15px;margin-bottom:8px;">总交易数：${stats.total_trades != null ? stats.total_trades : '0'}</div>
      <div style="display:flex;justify-content:space-between;">
        <div style="flex:1">
          <div>逐笔胜率：<span style="color:${stats.trade_based_win_rate>=50?'#28a745':'#dc3545'};">${stats.trade_based_win_rate != null ? stats.trade_based_win_rate.toFixed(1) : '9999.0'}%</span></div>
          <div>逐笔盈亏比：<span style="color:${stats.trade_based_rrr>=1?'#28a745':'#dc3545'};">${stats.trade_based_rrr != null ? stats.trade_based_rrr == Infinity ? '+∞' : stats.trade_based_rrr.toFixed(2) : '99999.00'}</span></div>
          <div>逐笔数学期望：<span style="color:${stats.trade_based_math_exp>=0?'#28a745':'#dc3545'};">${stats.trade_based_math_exp != null ? stats.trade_based_math_exp == Infinity ? '+∞' : stats.trade_based_math_exp.toFixed(2) : '99999.00'}</span></div>
        </div>
        <div style="flex:1">
          <div>日胜率：<span style="color:${stats.day_based_win_rate>=50?'#28a745':'#dc3545'};">${stats.day_based_win_rate != null ? stats.day_based_win_rate.toFixed(1) : '9999.0'}%</span></div>
          <div>日盈亏比：<span style="color:${stats.day_based_rrr>=1?'#28a745':'#dc3545'};">${stats.day_based_rrr != null ? stats.day_based_rrr == Infinity ? '+∞' : stats.day_based_rrr.toFixed(2) : '99999.00'}</span></div>
          <div>日数学期望：<span style="color:${stats.day_based_math_exp>=0?'#28a745':'#dc3545'};">${stats.day_based_math_exp != null ? stats.day_based_math_exp == Infinity ? '+∞' : stats.day_based_math_exp.toFixed(2) : '99999.00'}</span></div>
        </div>
      </div>
      <div style="margin-top:8px;font-size:13px;color:#888;">逐笔盈亏：</div>
      <div style="width:100%;height:100px;overflow-x:auto;overflow-y:hidden;"><canvas id="tradeBarChart" width="440" height="100"></canvas></div>
    `;
    $('#profitTooltip').html(html).css({
      left: e.pageX + 16,
      top: e.pageY - 10,
      display: 'block'
    });
    // 请求逐笔交易明细并渲染柱状图
    $.get('/statistics/trades_in_period', {start, end}, function(trades){
        if (!trades || trades.length === 0) return;

        // 在创建新图表前销毁旧图表
        //if (window.tradeBarChart) {
        //    window.tradeBarChart.destroy();
        //}

        let ctx = document.getElementById('tradeBarChart').getContext('2d');
        //window.tradeBarChart = new Chart(ctx, {
        new Chart(ctx, {
            type: 'bar',
            data: {
                labels: trades.map(t => t.open_datetime),
                datasets: [{
                    data: trades.map(t => t.net_profit),
                    backgroundColor: trades.map(t => t.net_profit > 0 ? '#28a745' : '#dc3545'),
                    barPercentage: 0.4,
                    categoryPercentage: 0.8,
                    barThickness: 6
                }]
            },
            options: {
                plugins: { legend: { display: false } },
                scales: {
                    x: {
                        display: true,
                        offset: true,
                        ticks: {
                            autoSkip: true,
                            maxTicksLimit: 8,
                            callback: function(value, index, values) {
                                let label = this.getLabelForValue(value);
                                return label ? label.slice(5, 10) : '';
                            }
                        }
                    },
                    y: { 
                        display: true,
                        ticks: {
                            callback: function(value) {
                                return value.toFixed(0);
                            }
                        }
                    }
                },
                animation: false,
                responsive: false,
                maintainAspectRatio: false
            }
        });
    });
});

$(document).on('mousemove', '.profit-cell', function(e){
    $('#profitTooltip').css({
      left: e.pageX + 16,
      top: e.pageY - 10
    });
});
$(document).on('mouseleave', '.profit-cell', function(){
    $('#profitTooltip').hide();
});
// 添加模态窗口相关函数
function ew_showTradeDetailsModal(label, trades, tradeCount) {
    const modal = document.getElementById('tradeDetailsModal');
    const modalTitle = document.getElementById('tradeDetailsTitle');
    const modalBody = document.getElementById('tradeDetailsBody');
    
    modalTitle.textContent = `${label} - 交易详情 (${tradeCount || trades.length} 笔交易)`;
    
    // 创建表格
    const table = document.createElement('table');
    table.className = 'table table-bordered table-striped table-hover';
    table.style.minWidth = '4000px';
    
    // 创建表头
    const thead = document.createElement('thead');
    thead.innerHTML = `
        <tr class="table-dark">
            <th>序号</th>
            <th>标的</th>
            <th>方向</th>
            <th>手数</th>
            <th>开仓价</th>
            <th>平仓价</th>
            <th>净利润</th>
            <th>总利润</th>
            <th>手续费</th>
            <th>开仓时间</th>
            <th>平仓时间</th>
            <th>持仓时间</th>
            <th>入场理由</th>
            <th>出场理由</th>
            <th>交易类型</th>
            <th>时段</th>
            <th>边</th>
            <th>第N笔</th>
            <th>评分</th>
            <th>评价</th>
            <th>每手点数</th>
            <th>总点数</th>
            <th>开仓订单类型</th>
            <th>平仓订单类型</th>
            <th>最大浮盈点数</th>
            <th>最大浮亏点数</th>
            <th>止损价格</th>
            <th>止盈价格</th>
            <th>开仓RRR</th>
            <th>平仓RRR</th>
            <th>FWR</th>
        </tr>
    `;
    table.appendChild(thead);
    
    // 创建表体
    const tbody = document.createElement('tbody');
    trades.forEach(trade => {
        const row = document.createElement('tr');
        
        // 盈亏状态样式
        const profitClass = trade.net_profit > 0 ? 'table-success' : 
                           trade.net_profit < 0 ? 'table-danger' : 'table-warning';
        row.className = profitClass;
        
        // 方向图标
        const directionIcon = trade.direction === 'Long' ? '🟢' : '🔴';
        
        // 格式化日期时间
        const formatDateTime = (dateStr) => {
            if (!dateStr) return '';
            const date = new Date(dateStr);
            return date.toLocaleString('zh-CN', {
                year: 'numeric',
                month: '2-digit',
                day: '2-digit',
                hour: '2-digit',
                minute: '2-digit'
            });
        };
        
        row.innerHTML = `
            <td><strong>${trade.index || ''}</strong></td>
            <td>${trade.symbol || ''}</td>
            <td>${directionIcon} ${trade.direction || ''}</td>
            <td>${trade.open_qty || ''}</td>
            <td>${trade.open_price || ''}</td>
            <td>${trade.close_price || ''}</td>
            <td><strong>${trade.net_profit ? trade.net_profit.toFixed(2) : ''}</strong></td>
            <td>${trade.gross_profit ? trade.gross_profit.toFixed(2) : ''}</td>
            <td>${trade.commission ? trade.commission.toFixed(2) : ''}</td>
            <td>${formatDateTime(trade.open_datetime)}</td>
            <td>${formatDateTime(trade.close_datetime)}</td>
            <td>${trade.holding_time || ''}</td>
            <td>${trade.entry_reason || ''}</td>
            <td>${trade.exit_reason || ''}</td>
            <td>${trade.trade_type || ''}</td>
            <td>${trade.session || ''}</td>
            <td>${trade.side || ''}</td>
            <td>${trade.nth_trade || ''}</td>
            <td>${trade.rating || ''}</td>
            <td>${trade.evaluation || ''}</td>
            <td>${trade.point_profit_per_lot || ''}</td>
            <td>${trade.total_points || ''}</td>
            <td>${trade.open_order_type || ''}</td>
            <td>${trade.close_order_type || ''}</td>
            <td>${trade.max_floating_profit_points || ''}</td>
            <td>${trade.max_floating_loss_points || ''}</td>
            <td>${trade.stop_loss_price || ''}</td>
            <td>${trade.take_profit_price || ''}</td>
            <td>${trade.open_rrr || ''}</td>
            <td>${trade.close_rrr || ''}</td>
            <td>${trade.fwr || ''}</td>
        `;
        tbody.appendChild(row);
    });
    table.appendChild(tbody);
    
    // 统计汇总
    const totalProfit = trades.reduce((sum, trade) => sum + (trade.net_profit || 0), 0);
    const totalGrossProfit = trades.reduce((sum, trade) => sum + (trade.gross_profit || 0), 0);
    const totalCommission = trades.reduce((sum, trade) => sum + (trade.commission || 0), 0);
    const winningTrades = trades.filter(trade => trade.net_profit > 0).length;
    const losingTrades = trades.filter(trade => trade.net_profit < 0).length;
    const breakEvenTrades = trades.filter(trade => trade.net_profit === 0).length;
    
    const summaryCard = document.createElement('div');
    summaryCard.className = 'card mb-3';
    summaryCard.innerHTML = `
        <div class="card-body">
            <h6 class="card-title">交易汇总</h6>
            <div class="row">
                <div class="col-md-2">
                    <strong>总笔数:</strong> ${trades.length}
                </div>
                <div class="col-md-2">
                    <strong>盈利笔数:</strong> <span class="text-success">${winningTrades}</span>
                </div>
                <div class="col-md-2">
                    <strong>亏损笔数:</strong> <span class="text-danger">${losingTrades}</span>
                </div>
                <div class="col-md-2">
                    <strong>打平笔数:</strong> <span class="text-warning">${breakEvenTrades}</span>
                </div>
                <div class="col-md-2">
                    <strong>胜率:</strong> ${trades.length > 0 ? ((winningTrades / trades.length) * 100).toFixed(1) : 0}%
                </div>
                <div class="col-md-2">
                    <strong>总净利润:</strong> <span class="${totalProfit > 0 ? 'text-success' : totalProfit < 0 ? 'text-danger' : 'text-warning'}">${totalProfit.toFixed(2)}</span>
                </div>
            </div>
            <div class="row mt-2">
                <div class="col-md-6">
                    <strong>总毛利润:</strong> <span class="${totalGrossProfit > 0 ? 'text-success' : totalGrossProfit < 0 ? 'text-danger' : 'text-warning'}">${totalGrossProfit.toFixed(2)}</span>
                </div>
                <div class="col-md-6">
                    <strong>总手续费:</strong> <span class="text-info">${totalCommission.toFixed(2)}</span>
                </div>
            </div>
        </div>
    `;
    
    // 创建包含表格的容器
    const tableContainer = document.createElement('div');
    tableContainer.className = 'table-responsive';
    tableContainer.appendChild(table);
    
    // 清空模态框内容并添加新内容
    modalBody.innerHTML = '';
    modalBody.appendChild(summaryCard);
    modalBody.appendChild(tableContainer);
    
    // 显示模态框
    const bootstrapModal = new bootstrap.Modal(modal, {
        keyboard: false,
        backdrop: 'static'
    });
    bootstrapModal.show();
}

function showPeriodDetail(start, end, stats) {
    // 确保所有值都是数字
    stats.total_profit = parseFloat(stats.total_profit) || 0;
    stats.trade_based_win_rate = parseFloat(stats.trade_based_win_rate) || 0;
    stats.trade_based_rrr = parseFloat(stats.trade_based_rrr) || 0;
    stats.total_trades = parseInt(stats.total_trades) || 0;

    // 设置模态窗口标题
    let title = '';
    if (start === end) {
        // 日视图
        const date = new Date(start);
        title = `${date.getFullYear()}年${date.getMonth() + 1}月${date.getDate()}日`;
    } else {
        // 周视图或月视图
        const startDate = new Date(start);
        const endDate = new Date(end);
        if (endDate.getTime() - startDate.getTime() <= 7 * 24 * 60 * 60 * 1000) {
            // 周视图
            title = `${startDate.getFullYear()}年第${getWeekNumber(startDate)}周 (${formatDateRange(startDate, endDate)})`;
        } else {
            // 月视图
            title = `${startDate.getFullYear()}年${startDate.getMonth() + 1}月`;
        }
    }
    $('.modal-title').text(title);

    // 请求交易明细
    $.get('/statistics/trades_in_period', {start, end}, function(trades) {
        // 保存原始数据
        modalTradesData = trades;

        console.log("modalTradesData:", modalTradesData);
        
        // 更新统计信息
        $('#modal_totalProfit').text((stats.total_profit > 0 ? '+' : '') + stats.total_profit.toFixed(2))
            .removeClass('text-success text-danger')
            .addClass(stats.total_profit > 0 ? 'text-success' : (stats.total_profit < 0 ? 'text-danger' : ''));
        $('#modal_winRate').text(stats.trade_based_win_rate.toFixed(1) + '%')
            .removeClass('text-success text-danger')
            .addClass(stats.trade_based_win_rate >= 50 ? 'text-success' : 'text-danger');
        $('#modal_totalTrades').text(stats.total_trades);
        $('#modal_profitFactor').text(stats.trade_based_rrr == Infinity ? '+∞' : stats.trade_based_rrr.toFixed(2))
            .removeClass('text-success text-danger')
            .addClass(stats.trade_based_rrr >= 1 ? 'text-success' : 'text-danger');

        // 更新 trade-based 统计
        $('#modal_trade_winrate')
            .text(stats.trade_based_win_rate.toFixed(1) + '%')
            .removeClass('text-success text-danger')
            .addClass(stats.trade_based_win_rate >= 50 ? 'text-success' : 'text-danger');
        $('#modal_trade_rrr')
            .text(stats.trade_based_rrr == Infinity ? '+∞' : stats.trade_based_rrr.toFixed(2))
            .removeClass('text-success text-danger')
            .addClass(stats.trade_based_rrr >= 1 ? 'text-success' : 'text-danger');
        $('#modal_trade_math_exp')
            .text(stats.trade_based_math_exp == Infinity ? '+∞' : stats.trade_based_math_exp.toFixed(2))
            .removeClass('text-success text-danger')
            .addClass(stats.trade_based_math_exp >= 0 ? 'text-success' : 'text-danger');
        // 更新 day-based 统计
        $('#modal_day_winrate')
            .text(stats.day_based_win_rate.toFixed(1) + '%')
            .removeClass('text-success text-danger')
            .addClass(stats.day_based_win_rate >= 50 ? 'text-success' : 'text-danger');
        $('#modal_day_rrr')
            .text(stats.day_based_rrr == Infinity ? '+∞' : stats.day_based_rrr.toFixed(2))
            .removeClass('text-success text-danger')
            .addClass(stats.day_based_rrr >= 1 ? 'text-success' : 'text-danger');
        $('#modal_day_math_exp')
            .text(stats.day_based_math_exp == Infinity ? '+∞' : stats.day_based_math_exp.toFixed(2))
            .removeClass('text-success text-danger')
            .addClass(stats.day_based_math_exp >= 0 ? 'text-success' : 'text-danger');

        // 渲染表格
        renderModalTrades();

        // 更新柱状图
        if(window.modalTradeChart) window.modalTradeChart.destroy();
        const ctx = document.getElementById('modal_tradeBarChart').getContext('2d');
        window.modalTradeChart = new Chart(ctx, {
            type: 'bar',
            data: {
                labels: trades.map(t => t.open_datetime),
                datasets: [{
                    data: trades.map(t => t.net_profit),
                    backgroundColor: trades.map(t => t.net_profit > 0 ? '#28a745' : '#dc3545'),
                    barPercentage: 0.4,
                    categoryPercentage: 0.8,
                    barThickness: 6
                }]
            },
            options: {
                plugins: { 
                    legend: { display: false },
                    tooltip: {
                        callbacks: {
                            label: function(context) {
                                return context.raw.toFixed(2);
                            }
                        }
                    }
                },
                scales: {
                    x: {
                        display: true,
                        offset: true,
                        ticks: {
                            autoSkip: true,
                            maxTicksLimit: 8,
                            callback: function(value, index, values) {
                                let label = this.getLabelForValue(value);
                                return label ? label.slice(5, 10) : '';
                            }
                        }
                    },
                    y: { 
                        display: true,
                        ticks: {
                            callback: function(value) {
                                return value.toFixed(0);
                            }
                        }
                    }
                },
                animation: false,
                responsive: true,
                maintainAspectRatio: false
            }
        });
    });

    // 显示模态窗口
    $('#periodDetailModal').modal('show');
}

// 修改点击事件处理
$(document).on('click', '.profit-cell', function(e){
    let stats = null;
    let start, end;
    
    if ($(this).data('date')) {
        // 日视图
        const date = $(this).data('date');
        //stats = window.ewStats?.daily?.[date];
        start = end = date;
    } else if ($(this).data('week')) {
        // 周视图
        start = $(this).data('week');
        end = $(this).data('week-end');
        //stats = aggregatePeriodStats(window.ewStats.daily, start, end);
    } else if ($(this).data('month')) {
        // 月视图
        const month = $(this).data('month');
        start = month + '-01';
        let [y, m] = month.split('-');
        let daysInMonth = new Date(y, m, 0).getDate();
        end = month + '-' + daysInMonth.toString().padStart(2, '0');
        //stats = aggregatePeriodStats(window.ewStats.daily, start, end);
    }

    stats = aggregatePeriodStats(window.ewStats.daily, start, end);
    if (stats && stats.total_trades > 0) {
        // 确保所有必要的统计值都有默认值
        stats.total_profit = stats.total_profit || 0;
        stats.win_rate = stats.win_rate || 0;
        stats.profit_factor = stats.profit_factor || 0;
        showPeriodDetail(start, end, stats);
    }
});

let currentProfitCell = null;

// profit-cell 点击时，记录当前cell
$(document).on('click', '.profit-cell', function(e){
    currentProfitCell = this;
    // ...原有内容...
});

// 模态窗口左右箭头事件
$('#modal-prev-btn').on('click', function() {
    if (!currentProfitCell) return;
    let prev = $(currentProfitCell).prevAll('.profit-cell:visible').filter(function(){
        return parseInt($(this).attr('data-total-trades')) > 0;
    }).first();
    if (prev.length) prev[0].click();
});
$('#modal-next-btn').on('click', function() {
    if (!currentProfitCell) return;
    let next = $(currentProfitCell).nextAll('.profit-cell:visible').filter(function(){
        return parseInt($(this).attr('data-total-trades')) > 0;
    }).first();
    if (next.length) next[0].click();
});

// 添加表格排序功能
let modalTradesData = []; // 存储原始数据
let currentSort = {
    column: null,
    direction: 'asc'
};

function sortModalTrades(column, direction) {
    if (!modalTradesData.length) return;
    
    modalTradesData.sort((a, b) => {
        let valueA = a[column];
        let valueB = b[column];
        
        // 处理日期时间
        if (column === 'open_datetime' || column === 'close_datetime') {
            valueA = new Date(valueA).getTime();
            valueB = new Date(valueB).getTime();
        }
        // 处理数字
        else if (column === 'open_price' || column === 'close_price' || column === 'open_qty' || column === 'net_profit' || column === 'index') {
            valueA = parseFloat(valueA) || 0;
            valueB = parseFloat(valueB) || 0;
        }
        // 处理字符串
        else {
            valueA = String(valueA || '').toLowerCase();
            valueB = String(valueB || '').toLowerCase();
        }
        
        if (valueA < valueB) return direction === 'asc' ? -1 : 1;
        if (valueA > valueB) return direction === 'asc' ? 1 : -1;
        return 0;
    });
    
    renderModalTrades();
}

function renderModalTrades() {
    const tbody = document.querySelector('#modal_tradesTable tbody');
    tbody.innerHTML = '';
    
    const visibleColumns = columnConfig.modal_window_columns.display_columns.filter(col => col.visible);
    console.log('模态窗口渲染 - 可见列:', visibleColumns);
    console.log('模态窗口渲染 - 交易数据示例:', modalTradesData[0]);
    
    modalTradesData.forEach(trade => {
        const row = document.createElement('tr');
        
        visibleColumns.forEach(col => {
            const td = document.createElement('td');
            const { content, className } = renderTableCell(col, trade, { isHtml: false });
            
            if (className) {
                td.className = className;
            }
            
            // 对于包含HTML的内容（如日期时间），使用innerHTML
            if (col.field === 'open_datetime' || col.field === 'close_datetime') {
                td.innerHTML = content;
            } else {
                td.textContent = content;
            }
            
            row.appendChild(td);
        });
        
        tbody.appendChild(row);
    });
}

// 添加表头点击事件处理
$(document).on('click', '#modal_tradesTable th.sortable', function() {
    const column = $(this).data('sort');
    const direction = currentSort.column === column && currentSort.direction === 'asc' ? 'desc' : 'asc';
    
    // 更新排序状态
    currentSort = { column, direction };
    
    // 更新表头样式
    $('#modal_tradesTable th').removeClass('asc desc');
    $(this).addClass(direction);
    
    // 执行排序
    sortModalTrades(column, direction);
});

// 添加表头样式
const style = document.createElement('style');
style.textContent = `
    #modal_tradesTable th.sortable {
        cursor: pointer;
        position: relative;
        padding-right: 20px;
    }
    #modal_tradesTable th.sortable:hover {
        background-color: #f8f9fa;
    }
    #modal_tradesTable th.sortable.asc::after,
    #modal_tradesTable th.sortable.desc::after {
        content: '';
        position: absolute;
        right: 8px;
        top: 50%;
        transform: translateY(-50%);
        border-left: 4px solid transparent;
        border-right: 4px solid transparent;
    }
    #modal_tradesTable th.sortable.asc::after {
        border-bottom: 4px solid #666;
    }
    #modal_tradesTable th.sortable.desc::after {
        border-top: 4px solid #666;
    }
`;
document.head.appendChild(style);

// 恢复卡片收起/展开按钮的事件绑定
$(document).off('click.dashboardCollapse').on('click.dashboardCollapse', '.dashboard-collapse-btn', function() {
    var target = $(this).data('target');
    $(target).toggleClass('collapsed');
    var icon = $(this).text();
    $(this).text(icon === '-' ? '+' : '-');
});

// 全局变量存储当前过滤条件
let currentFilters = {};

// 全局变量存储列配置
let columnConfig = {
    modal_window_columns: { display_columns: [] },
    best_worst_columns: { display_columns: [] }
};

// 加载列配置
function loadColumnConfig() {
    console.log('开始加载统计页面配置...');
    $.get('/api/statistics_config', function(config) {
        console.log('统计页面配置加载成功:', config);
        columnConfig = {
            modal_window_columns: config.modal_window_columns || { display_columns: [] },
            best_worst_columns: config.best_worst_columns || { display_columns: [] }
        };
        console.log('处理后的列配置:', columnConfig);
        
        // 应用其他配置设置
        applyPageSettings(config);
        
        // 生成表头
        generateTableHeaders();
    }).fail(function(xhr, status, error) {
        console.error('统计页面配置加载失败:', xhr, status, error);
        console.warn('Failed to load column config, using default settings');
        // 使用默认配置
        columnConfig = {
            modal_window_columns: {
                display_columns: [
                    { field: "index", header: "序号", visible: true, sortable: true },
                    { field: "symbol", header: "标的", visible: true, sortable: true },
                    { field: "open_datetime", header: "开仓时间", visible: true, sortable: true },
                    { field: "close_datetime", header: "平仓时间", visible: true, sortable: true },
                    { field: "open_price", header: "开仓价", visible: true, sortable: true },
                    { field: "close_price", header: "平仓价", visible: true, sortable: true },
                    { field: "open_qty", header: "手数", visible: true, sortable: true },
                    { field: "entry_reason", header: "开仓原因", visible: true, sortable: true },
                    { field: "exit_reason", header: "平仓原因", visible: true, sortable: true },
                    { field: "net_profit", header: "盈亏", visible: true, sortable: true },
                    { field: "side", header: "Side", visible: true, sortable: true }
                ]
            },
            best_worst_columns: {
                display_columns: [
                    { field: "index", header: "序号", visible: true, sortable: false },
                    { field: "symbol", header: "标的", visible: true, sortable: false },
                    { field: "open_datetime", header: "开时", visible: true, sortable: false },
                    { field: "close_datetime", header: "平时", visible: true, sortable: false },
                    { field: "open_price", header: "开价", visible: true, sortable: false },
                    { field: "close_price", header: "平价", visible: true, sortable: false },
                    { field: "open_qty", header: "手数", visible: true, sortable: false },
                    { field: "entry_reason", header: "开因", visible: true, sortable: false },
                    { field: "exit_reason", header: "平因", visible: true, sortable: false },
                    { field: "net_profit", header: "利润", visible: true, sortable: false },
                    { field: "side", header: "Side", visible: false, sortable: false }
                ]
            }
        };
        
        // 在失败情况下也应用默认设置
        applyPageSettings({
            dashboard_settings: { default_k_value: 5 },
            calendar_settings: { default_view: 'day' }
        });
        
        generateTableHeaders();
    });
}

// 应用页面设置
function applyPageSettings(config) {
    console.log('应用页面设置:', config);
    
    // 应用默认K值设置
    const defaultKValue = config.dashboard_settings?.default_k_value || 5;
    $('#ew_maxN').val(defaultKValue);
    console.log('设置默认K值:', defaultKValue);
    
    // 应用默认视图设置
    const defaultView = config.calendar_settings?.default_view || 'day';
    $('#ew_viewDay, #ew_viewWeek, #ew_viewMonth').removeClass('active');
    if (defaultView === 'week') {
        $('#ew_viewWeek').addClass('active');
    } else if (defaultView === 'month') {
        $('#ew_viewMonth').addClass('active');
    } else {
        $('#ew_viewDay').addClass('active');
    }
    console.log('设置默认视图:', defaultView);
    
    // 保存配置到全局变量以供后续使用
    window.pageConfig = config;
    
    // 使用新的K值刷新统计数据
    ew_fetchStats(defaultKValue);
}

// 生成表头
function generateTableHeaders() {
    console.log('开始生成表头...', columnConfig);
    
    // 模态窗口表头
    const modalHeader = $('#modal_tradesTableHeader');
    modalHeader.empty();
    const modalColumns = columnConfig.modal_window_columns.display_columns.filter(col => col.visible);
    console.log('模态窗口可见列:', modalColumns);
    modalColumns.forEach(col => {
        const th = $(`<th class="${col.sortable ? 'sortable' : ''}" data-sort="${col.field}">${col.header}</th>`);
        modalHeader.append(th);
    });
    
    // Best/Worst表头
    const lossHeader = $('#ew_maxNLossTableHeader');
    const winHeader = $('#ew_maxNWinTableHeader');
    lossHeader.empty();
    winHeader.empty();
    
    const bestWorstColumns = columnConfig.best_worst_columns.display_columns.filter(col => col.visible);
    console.log('Best/Worst可见列:', bestWorstColumns);
    bestWorstColumns.forEach(col => {
        const th = $(`<th>${col.header}</th>`);
        lossHeader.append(th.clone());
        winHeader.append(th.clone());
    });
    
    console.log('表头生成完成');
}

// 通用的单元格渲染函数
function renderTableCell(col, trade, options = {}) {
    const { 
        isHtml = false, 
        profitColor = '', 
        symbol = null, 
        openDate = null, 
        openTime = null, 
        closeDate = null, 
        closeTime = null 
    } = options;
    
    let content = '';
    let className = '';
    
    switch(col.field) {
        case 'index':
            content = trade.index || '';
            break;
        case 'symbol':
            if (symbol !== null) {
                content = symbol;
            } else {
                let sym = trade.symbol || '';
                if(sym.length > 3) sym = sym.slice(0, -3);
                content = sym;
            }
            break;
        case 'open_datetime':
            if (openDate !== null && openTime !== null) {
                content = `<div>${openDate}</div><div style='font-size:12px;color:#888;'>${openTime}</div>`;
                className = 'text-center align-middle';
            } else {
                const [date, time] = formatShortTime(trade.open_datetime);
                content = `<div>${date}</div><div style='font-size:12px;color:#888;'>${time}</div>`;
                className = 'text-center';
            }
            break;
        case 'close_datetime':
            if (closeDate !== null && closeTime !== null) {
                content = `<div>${closeDate}</div><div style='font-size:12px;color:#888;'>${closeTime}</div>`;
                className = 'text-center align-middle';
            } else {
                const [date, time] = formatShortTime(trade.close_datetime);
                content = `<div>${date}</div><div style='font-size:12px;color:#888;'>${time}</div>`;
                className = 'text-center';
            }
            break;
        case 'open_price':
            content = trade.open_price !== undefined ? trade.open_price : '';
            break;
        case 'close_price':
            content = trade.close_price !== undefined ? trade.close_price : '';
            break;
        case 'open_qty':
            content = trade.open_qty !== undefined ? trade.open_qty : '';
            break;
        case 'entry_reason':
            content = trade.entry_reason || '';
            break;
        case 'exit_reason':
            content = trade.exit_reason || '';
            break;
        case 'net_profit':
            if (isHtml && profitColor) {
                // Best/Worst表格使用传入的profitColor和net_profit_value
                content = trade.net_profit_value !== undefined ? trade.net_profit_value.toFixed(2) : '';
                className = profitColor.replace(/class=['"]([^'"]*)['"]/g, '$1');
            } else {
                // 模态窗口使用trade.net_profit
                const profit = trade.net_profit || 0;
                content = (profit > 0 ? '+' : '') + profit.toFixed(2);
                className = profit > 0 ? 'text-success' : 'text-danger';
            }
            break;
        case 'direction':
            content = trade.direction || '';
            break;
        case 'trade_type':
            content = trade.trade_type || '';
            break;
        case 'holding_time':
            content = trade.holding_time || '';
            break;
        case 'side':
            content = trade.side || '';
            break;
        default:
            content = trade[col.field] || '';
    }
    
    return { content, className };
}

// 生成Best/Worst表格行
function generateBestWorstTableRow(row, symbol, openDate, openTime, closeDate, closeTime, profitColor) {
    const visibleColumns = columnConfig.best_worst_columns.display_columns.filter(col => col.visible);
    let html = '<tr>';
    
    visibleColumns.forEach(col => {
        const { content, className } = renderTableCell(col, row, {
            isHtml: true,
            profitColor,
            symbol,
            openDate,
            openTime,
            closeDate,
            closeTime
        });
        
        const classAttr = className ? ` class="${className}"` : '';
        html += `<td${classAttr}>${content}</td>`;
    });
    
    html += '</tr>';
    return html;
}

// 过滤器相关函数
function initializeFilters() {
    // 获取过滤器选项数据
    $.get('/statistics/filter_options', function(data) {
        // 填充品种选择框
        const symbolSelect = $('#filter_symbol');
        symbolSelect.empty().append('<option value="">所有品种</option>');
        data.symbols.forEach(symbol => {
            symbolSelect.append(`<option value="${symbol}">${symbol}</option>`);
        });
        
        // 填充交易类型选择框
        const tradeTypeSelect = $('#filter_trade_type');
        tradeTypeSelect.empty().append('<option value="">所有类型</option>');
        data.trade_types.forEach(type => {
            tradeTypeSelect.append(`<option value="${type}">${type}</option>`);
        });
        
        // 填充时段选择框
        const sessionSelect = $('#filter_session');
        sessionSelect.empty().append('<option value="">所有时段</option>');
        data.sessions.forEach(session => {
            sessionSelect.append(`<option value="${session}">${session}</option>`);
        });
        
        // 填充入场理由选择框
        const entryReasonSelect = $('#filter_entry_reason');
        entryReasonSelect.empty().append('<option value="">所有理由</option>');
        data.entry_reasons.forEach(reason => {
            entryReasonSelect.append(`<option value="${reason}">${reason}</option>`);
        });
        
        // 填充止损理由选择框
        const stopLossReasonSelect = $('#filter_stop_loss_reason');
        stopLossReasonSelect.empty().append('<option value="">所有理由</option>');
        data.stop_loss_reasons.forEach(reason => {
            stopLossReasonSelect.append(`<option value="${reason}">${reason}</option>`);
        });
        
        // 填充止盈理由选择框
        const takeProfitReasonSelect = $('#filter_take_profit_reason');
        takeProfitReasonSelect.empty().append('<option value="">所有理由</option>');
        data.take_profit_reasons.forEach(reason => {
            takeProfitReasonSelect.append(`<option value="${reason}">${reason}</option>`);
        });
        
        // 填充其他离场理由选择框
        const otherExitReasonSelect = $('#filter_other_exit_reason');
        otherExitReasonSelect.empty().append('<option value="">所有理由</option>');
        data.other_exit_reasons.forEach(reason => {
            otherExitReasonSelect.append(`<option value="${reason}">${reason}</option>`);
        });
    });
}

function applyFilters() {
    console.log("=== 开始应用过滤器 ===");
    
    // 收集过滤条件，过滤掉空字符串
    const filterValue = (selector) => {
        const val = $(selector).val() || [];
        return Array.isArray(val) ? val.filter(v => v !== '') : val;
    };
    
    currentFilters = {
        symbols: filterValue('#filter_symbol'),
        directions: filterValue('#filter_direction'),
        trade_types: filterValue('#filter_trade_type'),
        sessions: filterValue('#filter_session'),
        sides: filterValue('#filter_side'),
        entry_reasons: filterValue('#filter_entry_reason'),
        stop_loss_reasons: filterValue('#filter_stop_loss_reason'),
        take_profit_reasons: filterValue('#filter_take_profit_reason'),
        other_exit_reasons: filterValue('#filter_other_exit_reason'),
        profit_status: $('#filter_profit_status').val() || '',
        profit_min: $('#filter_profit_min').val() || '',
        profit_max: $('#filter_profit_max').val() || '',
        duration_min: $('#filter_duration_min').val() || '',
        duration_max: $('#filter_duration_max').val() || ''
    };
    
    console.log("收集到的过滤条件:", currentFilters);
    
    // 调试：检查每个过滤器元素
    const filterElements = [
        'filter_symbol', 'filter_direction', 'filter_trade_type', 'filter_session', 'filter_side',
        'filter_entry_reason', 'filter_stop_loss_reason', 'filter_take_profit_reason', 
        'filter_other_exit_reason', 'filter_profit_status', 'filter_profit_min', 
        'filter_profit_max', 'filter_duration_min', 'filter_duration_max'
    ];
    
    filterElements.forEach(id => {
        const element = document.getElementById(id);
        if (!element) {
            console.warn(`⚠️ 过滤器元素不存在: ${id}`);
        } else {
            const value = $(element).val();
            console.log(`✅ ${id}: ${JSON.stringify(value)}`);
        }
    });
    
    // 检查是否有任何过滤条件
    const hasFilters = Object.values(currentFilters).some(value => {
        if (Array.isArray(value)) {
            return value.length > 0 && value.some(v => v !== '');
        }
        return value !== '';
    });
    
    // 显示/隐藏过滤状态
    if (hasFilters) {
        $('#filterStatus').show();
    } else {
        $('#filterStatus').hide();
    }
    
    // 重新获取统计数据
    let n = parseInt($('#ew_maxN').val()) || 5;
    ew_fetchStats(n);
    
    // 收起过滤器面板
    $('#filterPanel').slideUp();
    
    // 添加成功提示
    console.log("✅ 过滤器已应用，正在重新加载数据...");
}

function clearFilters() {
    // 清空所有过滤条件
    $('#filter_symbol').val([]);
    $('#filter_direction').val([]);
    $('#filter_trade_type').val([]);
    $('#filter_session').val([]);
    $('#filter_side').val([]);
    $('#filter_entry_reason').val([]);
    $('#filter_stop_loss_reason').val([]);
    $('#filter_take_profit_reason').val([]);
    $('#filter_other_exit_reason').val([]);
    $('#filter_profit_status').val('');
    $('#filter_profit_min').val('');
    $('#filter_profit_max').val('');
    $('#filter_duration_min').val('');
    $('#filter_duration_max').val('');
    
    currentFilters = {};
    $('#filterStatus').hide();
    
    // 重新获取统计数据
    let n = parseInt($('#ew_maxN').val()) || 5;
    ew_fetchStats(n);
}

function showFilterDetails() {
    let details = [];
    
    if (currentFilters.symbols && currentFilters.symbols.length > 0) {
        details.push(`品种: ${currentFilters.symbols.join(', ')}`);
    }
    if (currentFilters.directions && currentFilters.directions.length > 0) {
        details.push(`方向: ${currentFilters.directions.join(', ')}`);
    }
    if (currentFilters.trade_types && currentFilters.trade_types.length > 0) {
        details.push(`交易类型: ${currentFilters.trade_types.join(', ')}`);
    }
    if (currentFilters.sessions && currentFilters.sessions.length > 0) {
        details.push(`时段: ${currentFilters.sessions.join(', ')}`);
    }
    if (currentFilters.sides && currentFilters.sides.length > 0) {
        details.push(`Side: ${currentFilters.sides.join(', ')}`);
    }
    if (currentFilters.entry_reasons && currentFilters.entry_reasons.length > 0) {
        details.push(`入场理由: ${currentFilters.entry_reasons.join(', ')}`);
    }
    if (currentFilters.stop_loss_reasons && currentFilters.stop_loss_reasons.length > 0) {
        details.push(`止损理由: ${currentFilters.stop_loss_reasons.join(', ')}`);
    }
    if (currentFilters.take_profit_reasons && currentFilters.take_profit_reasons.length > 0) {
        details.push(`止盈理由: ${currentFilters.take_profit_reasons.join(', ')}`);
    }
    if (currentFilters.other_exit_reasons && currentFilters.other_exit_reasons.length > 0) {
        details.push(`其他离场理由: ${currentFilters.other_exit_reasons.join(', ')}`);
    }
    if (currentFilters.profit_status) {
        const statusMap = {
            'profitable': '盈利交易',
            'losing': '亏损交易',
            'breakeven': '持平交易'
        };
        details.push(`盈亏状态: ${statusMap[currentFilters.profit_status]}`);
    }
    if (currentFilters.profit_min || currentFilters.profit_max) {
        let range = '净利润范围: ';
        if (currentFilters.profit_min && currentFilters.profit_max) {
            range += `${currentFilters.profit_min} ~ ${currentFilters.profit_max}`;
        } else if (currentFilters.profit_min) {
            range += `>= ${currentFilters.profit_min}`;
        } else if (currentFilters.profit_max) {
            range += `<= ${currentFilters.profit_max}`;
        }
        details.push(range);
    }
    if (currentFilters.duration_min || currentFilters.duration_max) {
        let range = '持仓时间: ';
        if (currentFilters.duration_min && currentFilters.duration_max) {
            range += `${currentFilters.duration_min} ~ ${currentFilters.duration_max} 分钟`;
        } else if (currentFilters.duration_min) {
            range += `>= ${currentFilters.duration_min} 分钟`;
        } else if (currentFilters.duration_max) {
            range += `<= ${currentFilters.duration_max} 分钟`;
        }
        details.push(range);
    }
    
    if (details.length > 0) {
        alert('当前过滤条件:\n\n' + details.join('\n'));
    } else {
        alert('当前没有应用任何过滤条件');
    }
}

function updateFilterStatusDisplay(filterInfo) {
    if (filterInfo.filter_applied) {
        const beforeCount = filterInfo.total_trades_before_filter;
        const afterCount = filterInfo.total_trades_after_filter;
        const filteredCount = beforeCount - afterCount;
        
        // 更醒目的过滤状态显示
        let statusClass = 'alert-info';
        let statusIcon = 'fas fa-filter';
        let statusText = '';
        
        if (filteredCount > 0) {
            statusClass = 'alert-warning';
            statusIcon = 'fas fa-exclamation-triangle';
            statusText = `<strong>过滤器已生效！</strong> 从 ${beforeCount} 笔交易中过滤出 ${afterCount} 笔交易 (过滤掉 ${filteredCount} 笔)`;
        } else {
            statusText = `过滤器已应用，但所有 ${beforeCount} 笔交易都符合条件`;
        }
        
        $('#filterStatus').removeClass('alert-info alert-warning alert-success')
                          .addClass(statusClass)
                          .html(
            `<i class="${statusIcon}"></i> ${statusText} ` +
            `<button id="showFilterDetails" class="btn btn-sm btn-outline-dark ms-2">查看过滤条件</button>`
        );
        
        // 重新绑定点击事件
        $('#showFilterDetails').off('click').on('click', function() {
            showFilterDetails();
        });
        
        // 添加控制台提示
        console.log(`🎯 过滤器效果: ${beforeCount} → ${afterCount} 笔交易 (过滤掉 ${filteredCount} 笔)`);
    }
}

// 过滤器管理相关函数
function saveCurrentFilter() {
    const filterName = $('#filterNameInput').val().trim();
    if (!filterName) {
        alert('请输入过滤器名称');
        return;
    }
    
    // 检查是否有过滤条件
    const hasFilters = Object.values(currentFilters).some(value => {
        if (Array.isArray(value)) {
            return value.length > 0 && value.some(v => v !== '');
        }
        return value !== '';
    });
    
    if (!hasFilters) {
        alert('请先设置过滤条件');
        return;
    }
    
    // 保存过滤器
    $.ajax({
        url: '/statistics/save_filter',
        method: 'POST',
        contentType: 'application/json',
        data: JSON.stringify({
            name: filterName,
            conditions: currentFilters
        }),
        success: function(response) {
            if (response.success) {
                alert('过滤器保存成功！');
                $('#filterNameInput').val('');
                loadSavedFilters();
            } else {
                alert('保存失败: ' + response.message);
            }
        },
        error: function() {
            alert('保存失败，请稍后重试');
        }
    });
}

function loadSavedFilters() {
    $.get('/statistics/saved_filters', function(data) {
        const filters = data.filters || [];
        const dropdownList = $('#savedFiltersList');
        const manageList = $('#savedFiltersManage');
        
        if (filters.length === 0) {
            dropdownList.html('<li><span class="dropdown-item-text text-muted">暂无保存的过滤器</span></li>');
            manageList.html('<p class="text-muted">暂无保存的过滤器</p>');
        } else {
            // 更新下拉菜单
            let dropdownHtml = '';
            filters.forEach(filter => {
                dropdownHtml += `
                    <li>
                        <a class="dropdown-item" href="#" onclick="applySavedFilter(${filter.id})" title="应用过滤器: ${filter.name}">
                            <i class="fas fa-filter me-2"></i>${filter.name}
                        </a>
                    </li>
                `;
            });
            dropdownList.html(dropdownHtml);
            
            // 更新管理界面
            let manageHtml = '';
            filters.forEach(filter => {
                const conditionsSummary = getFilterConditionsSummary(filter.conditions);
                manageHtml += `
                    <div class="card mb-2">
                        <div class="card-body p-3">
                            <div class="d-flex justify-content-between align-items-start">
                                <div>
                                    <h6 class="mb-1">${filter.name}</h6>
                                    <small class="text-muted">创建时间: ${filter.created_at}</small>
                                    <div class="mt-2">
                                        <small class="text-info">${conditionsSummary}</small>
                                    </div>
                                </div>
                                <div>
                                    <button class="btn btn-sm btn-primary me-1" onclick="applySavedFilter(${filter.id})">
                                        <i class="fas fa-play"></i> 应用
                                    </button>
                                    <button class="btn btn-sm btn-danger" onclick="deleteSavedFilter(${filter.id}, '${filter.name}')">
                                        <i class="fas fa-trash"></i> 删除
                                    </button>
                                </div>
                            </div>
                        </div>
                    </div>
                `;
            });
            manageList.html(manageHtml);
        }
    });
}

function getFilterConditionsSummary(conditions) {
    let summary = [];
    
    if (conditions.symbols && conditions.symbols.length > 0) {
        summary.push(`品种: ${conditions.symbols.join(', ')}`);
    }
    if (conditions.directions && conditions.directions.length > 0) {
        summary.push(`方向: ${conditions.directions.join(', ')}`);
    }
    if (conditions.trade_types && conditions.trade_types.length > 0) {
        summary.push(`类型: ${conditions.trade_types.join(', ')}`);
    }
    if (conditions.sessions && conditions.sessions.length > 0) {
        summary.push(`时段: ${conditions.sessions.join(', ')}`);
    }
    if (conditions.sides && conditions.sides.length > 0) {
        summary.push(`Side: ${conditions.sides.join(', ')}`);
    }
    if (conditions.entry_reasons && conditions.entry_reasons.length > 0) {
        summary.push(`入场: ${conditions.entry_reasons.join(', ')}`);
    }
    if (conditions.stop_loss_reasons && conditions.stop_loss_reasons.length > 0) {
        summary.push(`止损: ${conditions.stop_loss_reasons.join(', ')}`);
    }
    if (conditions.take_profit_reasons && conditions.take_profit_reasons.length > 0) {
        summary.push(`止盈: ${conditions.take_profit_reasons.join(', ')}`);
    }
    if (conditions.other_exit_reasons && conditions.other_exit_reasons.length > 0) {
        summary.push(`其他出场: ${conditions.other_exit_reasons.join(', ')}`);
    }
    if (conditions.profit_status) {
        const statusMap = {
            'profitable': '盈利交易',
            'losing': '亏损交易', 
            'breakeven': '持平交易'
        };
        summary.push(`状态: ${statusMap[conditions.profit_status]}`);
    }
    if (conditions.profit_min || conditions.profit_max) {
        let range = '利润: ';
        if (conditions.profit_min && conditions.profit_max) {
            range += `${conditions.profit_min} ~ ${conditions.profit_max}`;
        } else if (conditions.profit_min) {
            range += `>= ${conditions.profit_min}`;
        } else if (conditions.profit_max) {
            range += `<= ${conditions.profit_max}`;
        }
        summary.push(range);
    }
    if (conditions.duration_min || conditions.duration_max) {
        let range = '时间: ';
        if (conditions.duration_min && conditions.duration_max) {
            range += `${conditions.duration_min} ~ ${conditions.duration_max}分钟`;
        } else if (conditions.duration_min) {
            range += `>= ${conditions.duration_min}分钟`;
        } else if (conditions.duration_max) {
            range += `<= ${conditions.duration_max}分钟`;
        }
        summary.push(range);
    }
    
    return summary.length > 0 ? summary.join('; ') : '无特定条件';
}

function applySavedFilter(filterId) {
    $.get('/statistics/saved_filters', function(data) {
        const filters = data.filters || [];
        const filter = filters.find(f => f.id === filterId);
        
        if (!filter) {
            alert('未找到指定的过滤器');
            return;
        }
        
        // 清除当前过滤条件
        clearFilters();
        
        // 应用保存的过滤条件
        const conditions = filter.conditions;
        
        if (conditions.symbols && conditions.symbols.length > 0) {
            $('#filter_symbol').val(conditions.symbols);
        }
        if (conditions.directions && conditions.directions.length > 0) {
            $('#filter_direction').val(conditions.directions);
        }
        if (conditions.trade_types && conditions.trade_types.length > 0) {
            $('#filter_trade_type').val(conditions.trade_types);
        }
        if (conditions.sessions && conditions.sessions.length > 0) {
            $('#filter_session').val(conditions.sessions);
        }
        if (conditions.sides && conditions.sides.length > 0) {
            $('#filter_side').val(conditions.sides);
        }
        if (conditions.entry_reasons && conditions.entry_reasons.length > 0) {
            $('#filter_entry_reason').val(conditions.entry_reasons);
        }
        if (conditions.stop_loss_reasons && conditions.stop_loss_reasons.length > 0) {
            $('#filter_stop_loss_reason').val(conditions.stop_loss_reasons);
        }
        if (conditions.take_profit_reasons && conditions.take_profit_reasons.length > 0) {
            $('#filter_take_profit_reason').val(conditions.take_profit_reasons);
        }
        if (conditions.other_exit_reasons && conditions.other_exit_reasons.length > 0) {
            $('#filter_other_exit_reason').val(conditions.other_exit_reasons);
        }
        if (conditions.profit_status) {
            $('#filter_profit_status').val(conditions.profit_status);
        }
        if (conditions.profit_min) {
            $('#filter_profit_min').val(conditions.profit_min);
        }
        if (conditions.profit_max) {
            $('#filter_profit_max').val(conditions.profit_max);
        }
        if (conditions.duration_min) {
            $('#filter_duration_min').val(conditions.duration_min);
        }
        if (conditions.duration_max) {
            $('#filter_duration_max').val(conditions.duration_max);
        }
        
        // 应用过滤器
        applyFilters();
        
        // 显示成功消息
        alert(`已应用过滤器: ${filter.name}`);
    });
}

function deleteSavedFilter(filterId, filterName) {
    if (!confirm(`确定要删除过滤器 "${filterName}" 吗？`)) {
        return;
    }
    
    $.ajax({
        url: '/statistics/delete_filter',
        method: 'POST',
        contentType: 'application/json',
        data: JSON.stringify({
            id: filterId
        }),
        success: function(response) {
            if (response.success) {
                alert('过滤器删除成功！');
                loadSavedFilters();
            } else {
                alert('删除失败: ' + response.message);
            }
        },
        error: function() {
            alert('删除失败，请稍后重试');
        }
    });
}

function showManageFiltersModal() {
    loadSavedFilters();
    $('#filterManageModal').modal('show');
}

// 统计页面配置管理函数
function showStatisticsConfigModal() {
    // 加载当前配置并显示配置界面
    $.get('/api/statistics_config', function(config) {
        populateConfigModal(config);
        $('#statisticsConfigModal').modal('show');
    });
}

function populateConfigModal(config) {
    // 填充模态窗口列配置
    populateColumnsConfig('modalColumnsConfig', config.modal_window_columns?.display_columns || []);
    
    // 填充Best/Worst窗口列配置
    populateColumnsConfig('bestWorstColumnsConfig', config.best_worst_columns?.display_columns || []);
    
    // 填充其他设置
    $('#defaultKValue').val(config.dashboard_settings?.default_k_value || 5);
    $('#defaultView').val(config.calendar_settings?.default_view || 'day');
}

function populateColumnsConfig(containerId, columns) {
    const container = $(`#${containerId}`);
    container.empty();
    
    columns.forEach((col, index) => {
        const columnDiv = $(`
            <div class="mb-2 p-2 border rounded">
                <div class="row align-items-center">
                    <div class="col-md-3">
                        <input type="text" class="form-control form-control-sm" value="${col.field}" readonly>
                    </div>
                    <div class="col-md-3">
                        <input type="text" class="form-control form-control-sm column-header" value="${col.header}" placeholder="表头名称">
                    </div>
                    <div class="col-md-3">
                        <div class="form-check">
                            <input class="form-check-input column-visible" type="checkbox" ${col.visible ? 'checked' : ''}>
                            <label class="form-check-label">可见</label>
                        </div>
                    </div>
                    <div class="col-md-3">
                        <div class="form-check">
                            <input class="form-check-input column-sortable" type="checkbox" ${col.sortable ? 'checked' : ''}>
                            <label class="form-check-label">可排序</label>
                        </div>
                    </div>
                </div>
            </div>
        `);
        container.append(columnDiv);
    });
}

function saveStatisticsConfig() {
    const modalColumns = collectColumnsConfig('modalColumnsConfig');
    const bestWorstColumns = collectColumnsConfig('bestWorstColumnsConfig');
    
    const config = {
        modal_window_columns: {
            display_columns: modalColumns
        },
        best_worst_columns: {
            display_columns: bestWorstColumns
        },
        dashboard_settings: {
            default_k_value: parseInt($('#defaultKValue').val()) || 5,
            refresh_interval: 0,
            auto_refresh: false
        },
        calendar_settings: {
            default_view: $('#defaultView').val() || 'day',
            time_zone: 'America/New_York'
        },
        chart_settings: {
            show_equity_curve: true,
            chart_height: 400,
            animation_enabled: false
        }
    };
    
    // 保存配置
    $.ajax({
        url: '/api/statistics_config',
        method: 'POST',
        contentType: 'application/json',
        data: JSON.stringify(config),
        success: function(response) {
            if (response.success) {
                alert('配置保存成功！请刷新页面以查看更改。');
                $('#statisticsConfigModal').modal('hide');
                // 重新加载配置
                loadColumnConfig();
            } else {
                alert('保存失败：' + response.message);
            }
        },
        error: function() {
            alert('保存失败，请检查网络连接。');
        }
    });
}

function collectColumnsConfig(containerId) {
    const columns = [];
    $(`#${containerId} .border.rounded`).each(function() {
        const field = $(this).find('input[readonly]').val();
        const header = $(this).find('.column-header').val();
        const visible = $(this).find('.column-visible').is(':checked');
        const sortable = $(this).find('.column-sortable').is(':checked');
        
        columns.push({
            field: field,
            header: header,
            visible: visible,
            sortable: sortable
        });
    });
    return columns;
}

// =============================================================================
// 自定义图表功能
// =============================================================================

let customChart = null;
let customChartData = null;

// 显示图表配置面板
function ew_showChartConfig() {
    const configPanel = document.getElementById('chartConfigPanel');
    configPanel.style.display = 'block';
    
    // 初始化配置
    ew_initChartConfig();
}

// 初始化图表配置
function ew_initChartConfig() {
    // 重置过滤器状态
    ew_updateChartFilterStatus();
    
    // 分段基数复选框事件
    document.getElementById('xEnableBinning').addEventListener('change', function() {
        const config = document.getElementById('xBinningConfig');
        if (this.checked) {
            config.style.display = 'block';
        } else {
            config.style.display = 'none';
        }
    });
    
    // 分段方式变化事件
    document.getElementById('xBinningMethod').addEventListener('change', function() {
        const label = document.getElementById('xBinningValueLabel');
        const input = document.getElementById('xBinningValue');
        
        switch(this.value) {
            case 'fixed_size':
                label.textContent = '区间大小';
                input.value = 100;
                input.min = 0.01;
                input.step = 'any';
                break;
            case 'fixed_count':
                label.textContent = '区间数量';
                input.value = 10;
                input.min = 2;
                input.step = 1;
                break;
            case 'percentile':
                label.textContent = '百分位数';
                input.value = 10;
                input.min = 1;
                input.step = 1;
                break;
            case 'auto':
                label.textContent = '最大区间数';
                input.value = 15;
                input.min = 5;
                input.step = 1;
                break;
        }
    });
    
    // 为过滤条件添加动态监听器
    const chartFilterConditions = document.getElementById('chartFilterConditions');
    if (chartFilterConditions) {
        // 使用事件委托来处理动态添加的过滤条件
        chartFilterConditions.addEventListener('change', function(e) {
            if (e.target.classList.contains('chart-filter-field')) {
                // 字段变化时，更新值输入框
                ew_updateFilterValueInput(e.target);
                ew_updateChartFilterDisplay();
            } else if (e.target.classList.contains('chart-filter-operator') || 
                       e.target.classList.contains('chart-filter-logic')) {
                ew_updateChartFilterDisplay();
            }
        });
        
        chartFilterConditions.addEventListener('input', function(e) {
            if (e.target.classList.contains('chart-filter-value')) {
                ew_updateChartFilterDisplay();
            }
        });
    }
}

// 添加图表过滤条件
function ew_addChartFilter() {
    const container = document.getElementById('chartFilterConditions');
    const filterId = 'chartFilter_' + Date.now();
    
    const filterHtml = `
        <div id="${filterId}" class="mb-3 p-3 border rounded bg-white">
            <div class="row align-items-center">
                <div class="col-md-3">
                    <select class="form-select chart-filter-field">
                        <!-- 基本信息 -->
                        <option value="index">序号</option>
                        <option value="trade_id">交易ID</option>
                        <option value="symbol">品种</option>
                        <option value="direction">方向</option>
                        <option value="side">边</option>
                        <option value="trade_type">交易类型</option>
                        <option value="session">交易时段</option>
                        <option value="nth_trade">第N笔交易</option>
                        
                        <!-- 价格和数量 -->
                        <option value="open_price">开仓价格</option>
                        <option value="close_price">平仓价格</option>
                        <option value="open_qty">开仓手数</option>
                        <option value="close_qty">平仓手数</option>
                        
                        <!-- 时间相关 -->
                        <option value="open_datetime">开仓时间</option>
                        <option value="close_datetime">平仓时间</option>
                        <option value="holding_time">持仓时间</option>
                        
                        <!-- 订单类型 -->
                        <option value="open_order_type">开仓订单类型</option>
                        <option value="close_order_type">平仓订单类型</option>
                        
                        <!-- 盈亏相关 -->
                        <option value="net_profit">净利润</option>
                        <option value="gross_profit">总利润</option>
                        <option value="commission">手续费</option>
                        <option value="point_profit_per_lot">每手点数盈亏</option>
                        <option value="total_points">总点数</option>
                        
                        <!-- 浮盈浮亏 -->
                        <option value="max_floating_profit_points">最大浮盈点数</option>
                        <option value="max_floating_profit_dollars">最大浮盈金额</option>
                        <option value="max_floating_loss_points">最大浮亏点数</option>
                        <option value="max_floating_loss_dollars">最大浮亏金额</option>
                        
                        <!-- 交易原因 -->
                        <option value="entry_reason">入场理由</option>
                        <option value="exit_reason">出场理由</option>
                        
                        <!-- 止损止盈 -->
                        <option value="stop_loss_price">止损价格</option>
                        <option value="stop_loss_reason">止损理由</option>
                        <option value="take_profit_price">止盈价格</option>
                        <option value="take_profit_reason">止盈理由</option>
                        
                        <!-- 评价指标 -->
                        <option value="rating">交易评分</option>
                        <option value="evaluation">交易评价</option>
                        <option value="open_rrr">开仓RRR</option>
                        <option value="close_rrr">平仓RRR</option>
                        <option value="fwr">FWR比率</option>
                    </select>
                </div>
                <div class="col-md-2">
                    <select class="form-select chart-filter-operator">
                        <option value="equals">等于</option>
                        <option value="not_equals">不等于</option>
                        <option value="contains">包含</option>
                        <option value="not_contains">不包含</option>
                        <option value="greater_than">大于</option>
                        <option value="less_than">小于</option>
                        <option value="greater_equal">大于等于</option>
                        <option value="less_equal">小于等于</option>
                        <option value="is_empty">为空</option>
                        <option value="is_not_empty">不为空</option>
                    </select>
                </div>
                <div class="col-md-4">
                    <input type="text" class="form-control chart-filter-value" placeholder="输入值">
                </div>
                <div class="col-md-2">
                    <select class="form-select chart-filter-logic">
                        <option value="and">且</option>
                        <option value="or">或</option>
                    </select>
                </div>
                <div class="col-md-1">
                    <button type="button" class="btn btn-sm btn-outline-danger" onclick="ew_removeChartFilter('${filterId}')">
                        <i class="fas fa-trash"></i>
                    </button>
                </div>
            </div>
        </div>
    `;
    
    container.insertAdjacentHTML('beforeend', filterHtml);
    ew_updateChartFilterStatus();
    
    // 初始化新添加的过滤器的值输入框
    setTimeout(() => {
        const newFieldSelect = document.querySelector(`#${filterId} .chart-filter-field`);
        if (newFieldSelect) {
            ew_updateFilterValueInput(newFieldSelect);
        }
    }, 100);
}

// 移除图表过滤条件
function ew_removeChartFilter(filterId) {
    const filterElement = document.getElementById(filterId);
    if (filterElement) {
        filterElement.remove();
        ew_updateChartFilterStatus();
    }
}

// 获取字段的固定选项
function ew_getFieldOptions(fieldName) {
    const fieldOptions = {
        'direction': ['Long', 'Short'],
        'side': ['Left', 'Right', 'Mid'],
        'session': ['RTH', 'ETH'],
        'trade_type': [
            'Scalp', 'Swing', 'Position', 'Intraday', 'mr', 'target', 
            'walmart', 'mis-op', 'scale-in', 'scale-out'
        ],
        'entry_reason': [
            '赌突破', '赌反转', 'breakout', 'DBDT', 's&r', 'wedge top', 'wedge bottom',
            'TR/CH reversal', 'TR/CH breakout', 'bull flag H1', 'bull flag H2', 'bull flag H3', 'bull flag H4',
            'bear flag L1', 'bear flag L2', 'bear flag L3', 'bear flag L4', '50%PB', 'opening reversal',
            'EMA S&R', '头肩顶', '头肩底', '杯柄', 'scale in', 'MTR', 'AIL', 'AIS', 'Late AIL', 'Late AIS',
            'good signal only', 'good context only', '直觉'
        ],
        'exit_reason': [
            '达到目标位', '达到止损位', '达到移动目标位', '达到移动止损位', '符合预期-打平离场',
            '符合预期-盈利离场', '符合预期-亏损离场', '符合预期-大盈利离场', '符合预期-大亏损离场',
            '不符合预期-打平离场', '不符合预期-亏损离场', '不符合预期-盈利离场', '不符合预期-几笔打平',
            '不符合预期-几笔微盈', '不符合预期-几笔微亏', '不符合预期-回开仓点', '收盘',
            '跟踪止盈-3Bar', '跟踪止盈-pt', '跟踪止盈-%', '操作失误', '未按交易计划执行-贪心',
            '未按交易计划执行-恐惧', '恐惧 - 反向大阳线/大阴线'
        ],
        'stop_loss_reason': [
            '区间另一边', '区间中间', '1R', '1.5R', '2R', '1TR.MM', '1.5TR.MM', '2TR.MM', '2.5TR.MM',
            '3TR.MM', '4TR.MM', '5TR.MM+', '1Leg.MM', '1.5Leg.MM', '2Leg.MM', '2.5Leg.MM', '3Leg.MM',
            '4Leg.MM', '5MM+', '1MM', '1.5MM', '2MM', '2.5MM', '3MM', '4MM', '5MM+', '2.5R', '3R', '4R',
            '5R+', '前高', '前低', '今日开盘', '今日高点', '今日低点', '昨日高点', '昨日低点', '昨日收盘',
            '50%PB', '通道起点', '高潮起点', '趋势线', 'EMA附近', '固定点数', '反向突破', '大阳/阴线之下/上',
            '打平价格', '等距运动AB=CD', '前方波段高低点', '大止损', '无目标'
        ],
        'take_profit_reason': [
            '区间另一边', '区间中间', '1R', '1.5R', '2R', '1TR.MM', '1.5TR.MM', '2TR.MM', '2.5TR.MM',
            '3TR.MM', '4TR.MM', '5TR.MM+', '1Leg.MM', '1.5Leg.MM', '2Leg.MM', '2.5Leg.MM', '3Leg.MM',
            '4Leg.MM', '5MM+', '1MM', '1.5MM', '2MM', '2.5MM', '3MM', '4MM', '5MM+', '2.5R', '3R', '4R',
            '5R+', '前高', '前低', '今日开盘', '今日高点', '今日低点', '昨日高点', '昨日低点', '昨日收盘',
            '50%PB', '通道起点', '高潮起点', '趋势线', 'EMA附近', '固定点数', '反向突破', '大阳/阴线之下/上',
            '打平价格', '等距运动AB=CD', '前方波段高低点', '大止损', '无目标'
        ],
        'rating': ['1', '2', '3', '4', '5'],
        'evaluation': ['优秀', '良好', '一般', '较差', '差'],
        'open_order_type': ['Market', 'Limit', 'Stop', 'Stop-Limit'],
        'close_order_type': ['Market', 'Limit', 'Stop', 'Stop-Limit']
    };
    
    return fieldOptions[fieldName] || null;
}

// 检查字段是否为日期时间字段
function ew_isDateTimeField(fieldName) {
    const dateTimeFields = [
        'open_datetime',
        'close_datetime'
    ];
    return dateTimeFields.includes(fieldName);
}

// 检查字段是否为时间持续字段
function ew_isTimeField(fieldName) {
    const timeFields = [
        'holding_time'
    ];
    return timeFields.includes(fieldName);
}

// 更新过滤器值输入框
function ew_updateFilterValueInput(fieldSelect) {
    const fieldName = fieldSelect.value;
    const filterContainer = fieldSelect.closest('[id^="chartFilter_"]');
    if (!filterContainer) return;
    
    const valueContainer = filterContainer.querySelector('.col-md-4');
    if (!valueContainer) return;
    
    const options = ew_getFieldOptions(fieldName);
    const currentValue = valueContainer.querySelector('.chart-filter-value')?.value || '';
    
    let inputHtml = '';
    
    if (options) {
        // 创建下拉框
        inputHtml = `
            <select class="form-select chart-filter-value">
                <option value="">请选择...</option>
                ${options.map(option => 
                    `<option value="${option}" ${option === currentValue ? 'selected' : ''}>${option}</option>`
                ).join('')}
            </select>
        `;
    } else if (ew_isDateTimeField(fieldName)) {
        // 创建日期时间选择器（带快速选择）
        const today = new Date();
        const yesterday = new Date(today);
        yesterday.setDate(yesterday.getDate() - 1);
        const lastWeek = new Date(today);
        lastWeek.setDate(lastWeek.getDate() - 7);
        const lastMonth = new Date(today);
        lastMonth.setMonth(lastMonth.getMonth() - 1);
        
        const formatDateTime = (date) => {
            return date.toISOString().slice(0, 16); // 格式化为 YYYY-MM-DDTHH:MM
        };
        
        inputHtml = `
            <div class="date-filter-container">
                <div class="input-group">
                    <input type="datetime-local" class="form-control chart-filter-value" value="${currentValue}" title="选择日期和时间">
                    <button class="btn btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false" title="快速选择日期">
                        <i class="fas fa-calendar-alt"></i>
                    </button>
                    <ul class="dropdown-menu">
                        <li><h6 class="dropdown-header">快速选择</h6></li>
                        <li><a class="dropdown-item" href="#" onclick="ew_setQuickDate(this, '${formatDateTime(today)}')">今天</a></li>
                        <li><a class="dropdown-item" href="#" onclick="ew_setQuickDate(this, '${formatDateTime(yesterday)}')">昨天</a></li>
                        <li><a class="dropdown-item" href="#" onclick="ew_setQuickDate(this, '${formatDateTime(lastWeek)}')">一周前</a></li>
                        <li><a class="dropdown-item" href="#" onclick="ew_setQuickDate(this, '${formatDateTime(lastMonth)}')">一个月前</a></li>
                        <li><hr class="dropdown-divider"></li>
                        <li><a class="dropdown-item" href="#" onclick="ew_setQuickDate(this, '')">清除</a></li>
                    </ul>
                </div>
            </div>
        `;
    } else if (ew_isTimeField(fieldName)) {
        // 创建时间持续输入框（带提示）
        inputHtml = `
            <div class="time-duration-container">
                <div class="input-group">
                    <input type="text" class="form-control chart-filter-value" placeholder="如: 2h 30m, 150m, 1d 3h" value="${currentValue}" title="输入时间持续，如: 2h 30m, 150m, 1d 3h">
                    <span class="input-group-text" title="支持格式: 1d 2h 30m, 150m, 2.5h">
                        <i class="fas fa-clock"></i>
                    </span>
                </div>
                <small class="form-text text-muted mt-1">
                    支持格式: 1d 2h 30m, 150m, 2.5h
                </small>
            </div>
        `;
    } else {
        // 创建文本输入框
        inputHtml = `
            <input type="text" class="form-control chart-filter-value" placeholder="输入值" value="${currentValue}">
        `;
    }
    
    valueContainer.innerHTML = inputHtml;
    
    // 重新绑定事件监听器
    const newValueInput = valueContainer.querySelector('.chart-filter-value');
    if (newValueInput) {
        newValueInput.addEventListener('change', function() {
            ew_updateChartFilterDisplay();
        });
        newValueInput.addEventListener('input', function() {
            ew_updateChartFilterDisplay();
        });
    }
    
    // 为日期时间字段添加额外的提示信息
    if (ew_isDateTimeField(fieldName)) {
        // 为日期时间字段更新操作符选项（移除包含/不包含等文本操作）
        const operatorSelect = filterContainer.querySelector('.chart-filter-operator');
        if (operatorSelect) {
            const originalValue = operatorSelect.value;
            operatorSelect.innerHTML = `
                <option value="equals">等于</option>
                <option value="not_equals">不等于</option>
                <option value="greater_than">晚于</option>
                <option value="less_than">早于</option>
                <option value="greater_than_or_equal">晚于等于</option>
                <option value="less_than_or_equal">早于等于</option>
                <option value="is_empty">为空</option>
                <option value="is_not_empty">不为空</option>
            `;
            // 恢复原来的值（如果仍然有效）
            if (['equals', 'not_equals', 'greater_than', 'less_than', 'greater_than_or_equal', 'less_than_or_equal', 'is_empty', 'is_not_empty'].includes(originalValue)) {
                operatorSelect.value = originalValue;
            }
        }
        
        // 为日期时间字段添加输入提示
        const valueInput = filterContainer.querySelector('.chart-filter-value');
        if (valueInput) {
            valueInput.placeholder = '格式: YYYY-MM-DD HH:MM 或 YYYY-MM-DD';
            valueInput.title = '支持格式: YYYY-MM-DD HH:MM 或 YYYY-MM-DD';
        }
    } else if (ew_isTimeField(fieldName)) {
        // 为时间持续字段更新操作符选项
        const operatorSelect = filterContainer.querySelector('.chart-filter-operator');
        if (operatorSelect) {
            const originalValue = operatorSelect.value;
            operatorSelect.innerHTML = `
                <option value="equals">等于</option>
                <option value="not_equals">不等于</option>
                <option value="contains">包含</option>
                <option value="greater_than">大于</option>
                <option value="less_than">小于</option>
                <option value="greater_equal">大于等于</option>
                <option value="less_equal">小于等于</option>
                <option value="is_empty">为空</option>
                <option value="is_not_empty">不为空</option>
            `;
            // 恢复原来的值（如果仍然有效）
            if (['equals', 'not_equals', 'contains', 'greater_than', 'less_than', 'greater_equal', 'less_equal', 'is_empty', 'is_not_empty'].includes(originalValue)) {
                operatorSelect.value = originalValue;
            }
        }
    } else if (!options) {
        // 为普通文本/数字字段恢复完整的操作符选项
        const operatorSelect = filterContainer.querySelector('.chart-filter-operator');
        if (operatorSelect) {
            const originalValue = operatorSelect.value;
            operatorSelect.innerHTML = `
                <option value="equals">等于</option>
                <option value="not_equals">不等于</option>
                <option value="contains">包含</option>
                <option value="not_contains">不包含</option>
                <option value="greater_than">大于</option>
                <option value="less_than">小于</option>
                <option value="greater_equal">大于等于</option>
                <option value="less_equal">小于等于</option>
                <option value="is_empty">为空</option>
                <option value="is_not_empty">不为空</option>
            `;
            // 恢复原来的值（如果仍然有效）
            if (['equals', 'not_equals', 'contains', 'not_contains', 'greater_than', 'less_than', 'greater_equal', 'less_equal', 'is_empty', 'is_not_empty'].includes(originalValue)) {
                operatorSelect.value = originalValue;
            }
        }
    }
}

// 快速设置日期
function ew_setQuickDate(element, dateValue) {
    // 找到对应的日期输入框
    const container = element.closest('.date-filter-container');
    const dateInput = container.querySelector('.chart-filter-value');
    
    if (dateInput) {
        dateInput.value = dateValue;
        // 触发change事件
        dateInput.dispatchEvent(new Event('change'));
    }
    
    // 阻止默认链接行为
    return false;
}

// 更新过滤器状态显示
function ew_updateChartFilterStatus() {
    const container = document.getElementById('chartFilterConditions');
    const filters = container.querySelectorAll('[id^="chartFilter_"]');
    const statusElement = document.getElementById('chartFilterStatus');
    
    if (filters.length === 0) {
        statusElement.textContent = '无过滤条件 - 将使用所有交易数据';
        statusElement.className = 'mt-2 text-muted small';
    } else {
        statusElement.textContent = `已设置 ${filters.length} 个过滤条件`;
        statusElement.className = 'mt-2 text-primary small fw-bold';
    }
    
    // 同步更新图表上方的过滤条件显示
    ew_updateChartFilterDisplay();
}

// 更新图表上方的过滤条件显示
function ew_updateChartFilterDisplay() {
    const container = document.getElementById('chartFilterConditions');
    const filters = container.querySelectorAll('[id^="chartFilter_"]');
    const displayElement = document.getElementById('chartFilterDisplay');
    const listElement = document.getElementById('chartFilterList');
    
    if (filters.length === 0) {
        displayElement.style.display = 'none';
    } else {
        displayElement.style.display = 'block';
        
        // 构建过滤条件列表
        const filterDescriptions = [];
        filters.forEach((filter, index) => {
            const field = filter.querySelector('.chart-filter-field').value;
            const fieldText = filter.querySelector('.chart-filter-field').options[filter.querySelector('.chart-filter-field').selectedIndex].text;
            const operator = filter.querySelector('.chart-filter-operator').value;
            const operatorText = filter.querySelector('.chart-filter-operator').options[filter.querySelector('.chart-filter-operator').selectedIndex].text;
            const value = filter.querySelector('.chart-filter-value').value;
            const logic = filter.querySelector('.chart-filter-logic').value;
            const logicText = filter.querySelector('.chart-filter-logic').options[filter.querySelector('.chart-filter-logic').selectedIndex].text;
            
            if (field && operator && (value || operator === 'is_empty' || operator === 'is_not_empty')) {
                let description = `<span class="badge bg-primary me-1">${fieldText}</span> ${operatorText}`;
                if (operator !== 'is_empty' && operator !== 'is_not_empty') {
                    description += ` <span class="fw-bold text-success">${value}</span>`;
                }
                
                // 添加逻辑连接词（除了最后一个条件）
                if (index < filters.length - 1) {
                    const logicSpan = logic === 'and' ? 
                        ' <span class="text-muted mx-1">且</span> ' : 
                        ' <span class="text-muted mx-1">或</span> ';
                    description += logicSpan;
                }
                
                filterDescriptions.push(description);
            }
        });
        
        listElement.innerHTML = filterDescriptions.join('');
    }
}

// 清除所有图表过滤条件
function ew_clearChartFilters() {
    const container = document.getElementById('chartFilterConditions');
    container.innerHTML = '';
    ew_updateChartFilterStatus();
    
    // 如果图表已经生成，则重新生成
    if (document.getElementById('customChartContainer').style.display !== 'none') {
        ew_updateCustomChart();
    }
}

// 重置图表配置
function ew_resetChartConfig() {
    // 清除所有过滤条件
    document.getElementById('chartFilterConditions').innerHTML = '';
    
    // 重置所有选择器
    document.getElementById('chartType').value = 'bar';
    document.getElementById('xField').value = 'symbol';
    document.getElementById('xSort').value = 'label_asc';
    document.getElementById('xIncludeEmpty').checked = true;
    document.getElementById('xMaxItems').value = '10';
    
    // 重置分段基数配置
    document.getElementById('xEnableBinning').checked = false;
    document.getElementById('xBinningConfig').style.display = 'none';
    document.getElementById('xBinningMethod').value = 'fixed_size';
    document.getElementById('xBinningValue').value = 100;
    document.getElementById('xBinningFormat').value = 'range';
    document.getElementById('xBinningIncludeEmpty').checked = false;
    document.getElementById('xBinningRoundValues').checked = true;
    
    document.getElementById('yField').value = 'count';
    document.getElementById('aggregation').value = 'sum';
    document.getElementById('colorScheme').value = 'default';
    document.getElementById('valueFormat').value = 'auto';
    document.getElementById('showDataLabels').checked = true;
    document.getElementById('showLegend').checked = true;
    document.getElementById('enableAnimation').checked = true;
    document.getElementById('chartTitle').value = '';
    document.getElementById('chartHeight').value = '400';
    
    ew_updateChartFilterStatus();
}

// 预览图表数据
async function ew_previewChartData() {
    try {
        const config = ew_getChartConfig();
        const filteredData = await ew_getFilteredTradeData(config);
        
        console.log('预览数据配置:', config);
        console.log('预览数据结果:', filteredData);
        
        // 获取字段显示名称
        const getFieldDisplayName = (field) => {
            const fieldMap = {
                'index': '序号',
                'symbol': '品种',
                'direction': '方向',
                'trade_type': '交易类型',
                'session': '交易时段',
                'open_price': '开仓价格',
                'close_price': '平仓价格',
                'open_qty': '开仓手数',
                'close_qty': '平仓手数',
                'net_profit': '净利润',
                'gross_profit': '总利润',
                'commission': '手续费',
                'point_profit_per_lot': '每手点数盈亏',
                'total_points': '总点数',
                'entry_reason': '入场理由',
                'exit_reason': '出场理由',
                'stop_loss_reason': '止损理由',
                'take_profit_reason': '止盈理由',
                'rating': '交易评分',
                'evaluation': '交易评价',
                'open_rrr': '开仓RRR',
                'close_rrr': '平仓RRR',
                'fwr': 'FWR比率',
                'holding_time': '持仓时间',
                'nth_trade': '第N笔交易'
            };
            return fieldMap[field] || field;
        };
        
        // 获取操作符显示名称
        const getOperatorDisplayName = (operator) => {
            const operatorMap = {
                'equals': '等于',
                'not_equals': '不等于',
                'contains': '包含',
                'not_contains': '不包含',
                'greater_than': '大于',
                'less_than': '小于',
                'greater_equal': '大于等于',
                'less_equal': '小于等于',
                'is_empty': '为空',
                'is_not_empty': '不为空'
            };
            return operatorMap[operator] || operator;
        };
        
        // 格式化过滤条件显示
        const filterDescription = config.filters.length > 0 ? 
            config.filters.map(f => {
                const fieldName = getFieldDisplayName(f.field);
                const operatorName = getOperatorDisplayName(f.operator);
                return f.operator === 'is_empty' || f.operator === 'is_not_empty' ? 
                    `${fieldName} ${operatorName}` : 
                    `${fieldName} ${operatorName} ${f.value}`;
            }).join(' 且 ') : 
            '无过滤条件';
        
        // 显示预览模态框
        const previewHtml = `
            <div class="modal fade" id="chartPreviewModal" tabindex="-1">
                <div class="modal-dialog modal-fullscreen">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h5 class="modal-title">📊 图表数据预览</h5>
                            <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                        </div>
                        <div class="modal-body">
                            <!-- 配置信息 -->
                            <div class="row mb-3">
                                <div class="col-md-6">
                                    <div class="card">
                                        <div class="card-body p-2">
                                            <h6 class="card-title mb-1">📊 图表配置</h6>
                                            <div class="small">
                                                <div><strong>图表类型:</strong> ${document.getElementById('chartType').options[document.getElementById('chartType').selectedIndex].text}</div>
                                                <div><strong>X轴字段:</strong> ${document.getElementById('xField').options[document.getElementById('xField').selectedIndex].text}</div>
                                                <div><strong>Y轴字段:</strong> ${document.getElementById('yField').options[document.getElementById('yField').selectedIndex].text}</div>
                                                <div><strong>聚合方式:</strong> ${document.getElementById('aggregation').options[document.getElementById('aggregation').selectedIndex].text}</div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <div class="col-md-6">
                                    <div class="card">
                                        <div class="card-body p-2">
                                            <h6 class="card-title mb-1">🔍 过滤条件</h6>
                                            <div class="small text-muted">${filterDescription}</div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                            
                            <!-- 数据统计 -->
                            <div class="row mb-3">
                                <div class="col-md-4">
                                    <div class="card bg-primary text-white">
                                        <div class="card-body p-2 text-center">
                                            <h6 class="card-title mb-1">📊 总记录数</h6>
                                            <h4 class="mb-0">${filteredData.records.length}</h4>
                                            ${filteredData.records.length > 100 ? '<small class="text-warning">显示前100条</small>' : ''}
                                        </div>
                                    </div>
                                </div>
                                <div class="col-md-4">
                                    <div class="card bg-success text-white">
                                        <div class="card-body p-2 text-center">
                                            <h6 class="card-title mb-1">📈 盈利交易</h6>
                                            <h4 class="mb-0">${filteredData.records.filter(r => (r.net_profit || 0) > 0).length}</h4>
                                            <small>占比 ${((filteredData.records.filter(r => (r.net_profit || 0) > 0).length / filteredData.records.length) * 100).toFixed(1)}%</small>
                                        </div>
                                    </div>
                                </div>
                                <div class="col-md-4">
                                    <div class="card bg-danger text-white">
                                        <div class="card-body p-2 text-center">
                                            <h6 class="card-title mb-1">📉 亏损交易</h6>
                                            <h4 class="mb-0">${filteredData.records.filter(r => (r.net_profit || 0) < 0).length}</h4>
                                            <small>占比 ${((filteredData.records.filter(r => (r.net_profit || 0) < 0).length / filteredData.records.length) * 100).toFixed(1)}%</small>
                                        </div>
                                    </div>
                                </div>
                            </div>
                            
                            <!-- 数据表格 -->
                            <div class="table-responsive" style="max-height: 500px; overflow-x: auto;">
                                <table class="table table-sm table-striped table-hover" style="min-width: 2500px;">
                                    <thead class="table-dark sticky-top">
                                        <tr>
                                            <!-- 基础信息 -->
                                            <th style="min-width: 80px;">DB序号</th>
                                            <th style="min-width: 120px;">交易ID</th>
                                            <th style="min-width: 80px;">品种</th>
                                            <th style="min-width: 80px;">方向</th>
                                            <th style="min-width: 80px;">类型</th>
                                            <th style="min-width: 80px;">边</th>
                                            <th style="min-width: 80px;">第N笔</th>
                                            <th style="min-width: 80px;">时段</th>
                                            
                                            <!-- 价格信息 -->
                                            <th style="min-width: 90px;">开仓价</th>
                                            <th style="min-width: 90px;">平仓价</th>
                                            <th style="min-width: 80px;">开仓量</th>
                                            <th style="min-width: 80px;">平仓量</th>
                                            <th style="min-width: 100px;">开仓订单</th>
                                            <th style="min-width: 100px;">平仓订单</th>
                                            
                                            <!-- 盈亏信息 -->
                                            <th style="min-width: 90px;">净利润</th>
                                            <th style="min-width: 90px;">总利润</th>
                                            <th style="min-width: 80px;">手续费</th>
                                            <th style="min-width: 100px;">每手点数</th>
                                            <th style="min-width: 80px;">总点数</th>
                                            
                                            <!-- 时间信息 -->
                                            <th style="min-width: 120px;">开仓时间</th>
                                            <th style="min-width: 120px;">平仓时间</th>
                                            <th style="min-width: 100px;">持仓时间</th>
                                            
                                            <!-- 浮盈浮亏 -->
                                            <th style="min-width: 100px;">最大浮盈点</th>
                                            <th style="min-width: 100px;">最大浮盈$</th>
                                            <th style="min-width: 100px;">最大浮亏点</th>
                                            <th style="min-width: 100px;">最大浮亏$</th>
                                            
                                            <!-- 交易理由 -->
                                            <th style="min-width: 120px;">入场理由</th>
                                            <th style="min-width: 120px;">出场理由</th>
                                            
                                            <!-- 止损止盈 -->
                                            <th style="min-width: 90px;">止损价</th>
                                            <th style="min-width: 120px;">止损理由</th>
                                            <th style="min-width: 90px;">止盈价</th>
                                            <th style="min-width: 120px;">止盈理由</th>
                                            
                                            <!-- 评价指标 -->
                                            <th style="min-width: 80px;">评分</th>
                                            <th style="min-width: 120px;">评价</th>
                                            <th style="min-width: 80px;">开仓RRR</th>
                                            <th style="min-width: 80px;">平仓RRR</th>
                                            <th style="min-width: 80px;">FWR</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        ${filteredData.records.slice(0, 100).map((record) => {
                                            const netProfit = parseFloat(record.net_profit || 0);
                                            const grossProfit = parseFloat(record.gross_profit || 0);
                                            const profitClass = netProfit > 0 ? 'text-success fw-bold' : 
                                                              netProfit < 0 ? 'text-danger fw-bold' : 'text-muted';
                                            const directionClass = record.direction === 'Long' ? 'text-primary' : 'text-warning';
                                            const ratingClass = (record.rating || 0) >= 4 ? 'text-success' : 
                                                              (record.rating || 0) >= 3 ? 'text-warning' : 'text-danger';
                                            
                                            const formatNumber = (num, decimals = 2) => {
                                                return num != null ? parseFloat(num).toFixed(decimals) : '-';
                                            };
                                            
                                            const formatDateTime = (dateStr) => {
                                                if (!dateStr) return '-';
                                                try {
                                                    return new Date(dateStr).toLocaleString('zh-CN', {
                                                        month: '2-digit', day: '2-digit', 
                                                        hour: '2-digit', minute: '2-digit'
                                                    });
                                                } catch {
                                                    return dateStr;
                                                }
                                            };
                                            
                                            return `
                                                <tr>
                                                    <!-- 基础信息 -->
                                                    <td><span class="badge bg-secondary">${record.index || '-'}</span></td>
                                                    <td><small class="font-monospace">${record.trade_id || '-'}</small></td>
                                                    <td><strong class="text-primary">${record.symbol || '-'}</strong></td>
                                                    <td><span class="${directionClass}">${record.direction || '-'}</span></td>
                                                    <td><span class="badge bg-info">${record.trade_type || '-'}</span></td>
                                                    <td><span class="badge bg-secondary">${record.side || '-'}</span></td>
                                                    <td><span class="badge bg-dark">${record.nth_trade || '-'}</span></td>
                                                    <td><span class="badge bg-success">${record.session || '-'}</span></td>
                                                    
                                                    <!-- 价格信息 -->
                                                    <td>${formatNumber(record.open_price)}</td>
                                                    <td>${formatNumber(record.close_price)}</td>
                                                    <td>${formatNumber(record.open_qty, 1)}</td>
                                                    <td>${formatNumber(record.close_qty, 1)}</td>
                                                    <td><small class="text-muted">${record.open_order_type || '-'}</small></td>
                                                    <td><small class="text-muted">${record.close_order_type || '-'}</small></td>
                                                    
                                                    <!-- 盈亏信息 -->
                                                    <td><span class="${profitClass}">${formatNumber(netProfit)}</span></td>
                                                    <td><span class="${grossProfit >= 0 ? 'text-success' : 'text-danger'}">${formatNumber(grossProfit)}</span></td>
                                                    <td class="text-warning">${formatNumber(record.commission)}</td>
                                                    <td>${formatNumber(record.point_profit_per_lot)}</td>
                                                    <td>${formatNumber(record.total_points)}</td>
                                                    
                                                    <!-- 时间信息 -->
                                                    <td><small>${formatDateTime(record.open_datetime)}</small></td>
                                                    <td><small>${formatDateTime(record.close_datetime)}</small></td>
                                                    <td><small class="font-monospace">${record.holding_time || '-'}</small></td>
                                                    
                                                    <!-- 浮盈浮亏 -->
                                                    <td class="text-success">${formatNumber(record.max_floating_profit_points)}</td>
                                                    <td class="text-success">${formatNumber(record.max_floating_profit_dollars)}</td>
                                                    <td class="text-danger">${formatNumber(record.max_floating_loss_points)}</td>
                                                    <td class="text-danger">${formatNumber(record.max_floating_loss_dollars)}</td>
                                                    
                                                    <!-- 交易理由 -->
                                                    <td><small class="text-muted">${record.entry_reason || '-'}</small></td>
                                                    <td><small class="text-muted">${record.exit_reason || '-'}</small></td>
                                                    
                                                    <!-- 止损止盈 -->
                                                    <td class="text-danger">${formatNumber(record.stop_loss_price)}</td>
                                                    <td><small class="text-muted">${record.stop_loss_reason || '-'}</small></td>
                                                    <td class="text-success">${formatNumber(record.take_profit_price)}</td>
                                                    <td><small class="text-muted">${record.take_profit_reason || '-'}</small></td>
                                                    
                                                    <!-- 评价指标 -->
                                                    <td>
                                                        ${record.rating ? `<span class="${ratingClass}">
                                                            ${'★'.repeat(record.rating)}${'☆'.repeat(5-record.rating)}
                                                        </span>` : '-'}
                                                    </td>
                                                    <td><small class="text-muted">${record.evaluation || '-'}</small></td>
                                                    <td class="text-info">${formatNumber(record.open_rrr)}</td>
                                                    <td class="text-info">${formatNumber(record.close_rrr)}</td>
                                                    <td class="text-primary">${formatNumber(record.fwr)}</td>
                                                </tr>
                                            `;
                                        }).join('')}
                                        ${filteredData.records.length > 100 ? `
                                            <tr class="table-warning">
                                                <td colspan="36" class="text-center">
                                                    <i class="fas fa-info-circle me-1"></i>
                                                    还有 ${filteredData.records.length - 100} 条记录未显示
                                                </td>
                                            </tr>
                                        ` : ''}
                                    </tbody>
                                </table>
                            </div>
                            
                            <!-- 统计摘要 -->
                            <div class="row mt-3">
                                <div class="col-md-3">
                                    <div class="text-center">
                                        <div class="text-muted small">总记录数</div>
                                        <div class="fw-bold">${filteredData.records.length}</div>
                                    </div>
                                </div>
                                <div class="col-md-3">
                                    <div class="text-center">
                                        <div class="text-muted small">盈利交易</div>
                                        <div class="fw-bold text-success">${filteredData.records.filter(r => (r.net_profit || 0) > 0).length}</div>
                                    </div>
                                </div>
                                <div class="col-md-3">
                                    <div class="text-center">
                                        <div class="text-muted small">亏损交易</div>
                                        <div class="fw-bold text-danger">${filteredData.records.filter(r => (r.net_profit || 0) < 0).length}</div>
                                    </div>
                                </div>
                                <div class="col-md-3">
                                    <div class="text-center">
                                        <div class="text-muted small">总净利润</div>
                                        <div class="fw-bold ${filteredData.records.reduce((sum, r) => sum + (parseFloat(r.net_profit) || 0), 0) >= 0 ? 'text-success' : 'text-danger'}">
                                            ${filteredData.records.reduce((sum, r) => sum + (parseFloat(r.net_profit) || 0), 0).toFixed(2)}
                                        </div>
                                    </div>
                                </div>
                            </div>
                            
                            <!-- 底部统计摘要 -->
                            <div class="row mt-3 pt-3 border-top">
                                <div class="col-md-12">
                                    <div class="alert alert-info">
                                        <h6 class="alert-heading mb-2">📊 快速统计摘要</h6>
                                        <div class="row text-center">
                                            <div class="col-md-2">
                                                <div class="small">
                                                    <strong>总净利润</strong><br>
                                                    <span class="${(filteredData.records.reduce((sum, r) => sum + (parseFloat(r.net_profit) || 0), 0)) >= 0 ? 'text-success' : 'text-danger'} fw-bold">
                                                        ${(filteredData.records.reduce((sum, r) => sum + (parseFloat(r.net_profit) || 0), 0)).toFixed(2)}
                                                    </span>
                                                </div>
                                            </div>
                                            <div class="col-md-2">
                                                <div class="small">
                                                    <strong>平均盈利</strong><br>
                                                    <span class="${(filteredData.records.reduce((sum, r) => sum + (parseFloat(r.net_profit) || 0), 0) / filteredData.records.length) >= 0 ? 'text-success' : 'text-danger'} fw-bold">
                                                        ${(filteredData.records.reduce((sum, r) => sum + (parseFloat(r.net_profit) || 0), 0) / filteredData.records.length).toFixed(2)}
                                                    </span>
                                                </div>
                                            </div>
                                            <div class="col-md-2">
                                                <div class="small">
                                                    <strong>胜率</strong><br>
                                                    <span class="text-info fw-bold">
                                                        ${filteredData.records.length > 0 ? ((filteredData.records.filter(r => (r.net_profit || 0) > 0).length / filteredData.records.length) * 100).toFixed(1) : '0.0'}%
                                                    </span>
                                                </div>
                                            </div>
                                            <div class="col-md-2">
                                                <div class="small">
                                                    <strong>最大盈利</strong><br>
                                                    <span class="text-success fw-bold">
                                                        ${filteredData.records.length > 0 ? Math.max(...filteredData.records.map(r => parseFloat(r.net_profit) || 0)).toFixed(2) : '0.00'}
                                                    </span>
                                                </div>
                                            </div>
                                            <div class="col-md-2">
                                                <div class="small">
                                                    <strong>最大亏损</strong><br>
                                                    <span class="text-danger fw-bold">
                                                        ${filteredData.records.length > 0 ? Math.min(...filteredData.records.map(r => parseFloat(r.net_profit) || 0)).toFixed(2) : '0.00'}
                                                    </span>
                                                </div>
                                            </div>
                                            <div class="col-md-2">
                                                <div class="small">
                                                    <strong>平均评分</strong><br>
                                                    <span class="text-warning fw-bold">
                                                        ${(() => {
                                                            const ratedRecords = filteredData.records.filter(r => r.rating);
                                                            if (ratedRecords.length === 0) return '0.0';
                                                            const avgRating = ratedRecords.reduce((sum, r) => sum + (parseFloat(r.rating) || 0), 0) / ratedRecords.length;
                                                            return avgRating.toFixed(1);
                                                        })()}
                                                    </span>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div class="modal-footer bg-light">
                            <button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">
                                <i class="fas fa-times me-1"></i>关闭
                            </button>
                            <button type="button" class="btn btn-success" onclick="navigator.clipboard.writeText(JSON.stringify(filteredData.records, null, 2)).then(() => alert('数据已复制到剪贴板')).catch(() => alert('复制失败'))">
                                <i class="fas fa-copy me-1"></i>复制数据
                            </button>
                            <button type="button" class="btn btn-primary" onclick="$('#chartPreviewModal').modal('hide'); ew_updateCustomChart();">
                                <i class="fas fa-chart-bar me-1"></i>生成图表
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        `;
        
        // 移除现有模态框
        const existingModal = document.getElementById('chartPreviewModal');
        if (existingModal) existingModal.remove();
        
        // 添加新模态框
        document.body.insertAdjacentHTML('beforeend', previewHtml);
        
        // 显示模态框
        const modal = new bootstrap.Modal(document.getElementById('chartPreviewModal'));
        modal.show();
        
    } catch (error) {
        console.error('预览数据失败:', error);
        alert('预览数据失败: ' + error.message);
    }
}

// 隐藏图表配置面板
function ew_hideChartConfig() {
    const configPanel = document.getElementById('chartConfigPanel');
    configPanel.style.display = 'none';
}

// 初始化自定义图表过滤器选项
function ew_initCustomChartFilters(stats) {
    // 初始化品种过滤器
    const symbolFilter = document.getElementById('symbolFilter');
    if (!symbolFilter) {
        console.log('symbolFilter 元素未找到，跳过初始化');
        return;
    }
    
    symbolFilter.innerHTML = '<option value="">全部品种</option>';
    
    if (stats.symbols && Object.keys(stats.symbols).length > 0) {
        Object.keys(stats.symbols).forEach(symbol => {
            const option = document.createElement('option');
            option.value = symbol;
            option.textContent = symbol;
            symbolFilter.appendChild(option);
        });
    }
    
    // 初始化交易类型过滤器
    const tradeTypeFilter = document.getElementById('tradeTypeFilter');
    if (!tradeTypeFilter) {
        console.log('tradeTypeFilter 元素未找到，跳过初始化');
        return;
    }
    
    tradeTypeFilter.innerHTML = '<option value="">全部类型</option>';
    
    // 从全局配置中获取交易类型
    if (window.filterOptions && window.filterOptions.trade_types) {
        window.filterOptions.trade_types.forEach(type => {
            const option = document.createElement('option');
            option.value = type;
            option.textContent = type;
            tradeTypeFilter.appendChild(option);
        });
    }
}

// 高级数据处理
function ew_processAdvancedChartData(trades, config) {
    if (!trades || trades.length === 0) {
        return { labels: [], datasets: [] };
    }
    
    const xField = config.xField;
    const yField = config.yField;
    const aggregation = config.aggregation;
    
    // 根据X轴字段分组数据
    const groups = {};
    
    trades.forEach(trade => {
        let xValue = ew_getAdvancedFieldValue(trade, xField);
        
        // 如果启用了分段基数，对数值字段进行分段处理
        if (config.xEnableBinning && ew_isNumericField(config.xField)) {
            xValue = ew_applyBinning(xValue, config, trades);
        }
        
        // 处理空值
        if (!config.xIncludeEmpty && (!xValue || xValue === '' || xValue === '未知')) {
            return;
        }
        
        if (!groups[xValue]) {
            groups[xValue] = [];
        }
        groups[xValue].push(trade);
    });
    
    // 排序和限制数量
    let labels = Object.keys(groups);
    const labelValuePairs = labels.map(label => ({
        label: label,
        value: ew_aggregateAdvancedValue(groups[label], yField, aggregation),
        count: groups[label].length
    }));
    
    // 排序
    switch (config.xSort) {
        case 'label_asc':
            labelValuePairs.sort((a, b) => ew_compareLabels(a.label, b.label));
            break;
        case 'label_desc':
            labelValuePairs.sort((a, b) => ew_compareLabels(b.label, a.label));
            break;
        case 'value_asc':
            labelValuePairs.sort((a, b) => a.value - b.value);
            break;
        case 'value_desc':
            labelValuePairs.sort((a, b) => b.value - a.value);
            break;
        case 'count_desc':
            labelValuePairs.sort((a, b) => b.count - a.count);
            break;
    }
    
    // 限制数量
    if (config.xMaxItems > 0) {
        labelValuePairs.splice(config.xMaxItems);
    }
    
    labels = labelValuePairs.map(pair => pair.label);
    const dataValues = labelValuePairs.map(pair => pair.value);
    
    // 格式化数值
    const formattedValues = dataValues.map(value => ew_formatValue(value, config.valueFormat));
    
    // 保存分组后的交易详情，用于tooltip显示
    const tradeDetails = labels.map(label => {
        const trades = groups[label];
        if (!trades || trades.length === 0) return [];
        
        // 返回基本交易信息用于简单tooltip显示
        return trades.slice(0, 10).map(trade => ({
            index: trade.index,
            symbol: trade.symbol,
            direction: trade.direction,
            net_profit: trade.net_profit,
            open_price: trade.open_price,
            close_price: trade.close_price,
            trade_type: trade.trade_type
        }));
    });

    // 保存完整交易信息用于点击模态框显示
    const fullTradeDetails = labels.map(label => {
        const trades = groups[label];
        if (!trades || trades.length === 0) return [];
        
        // 返回所有交易的完整信息
        return trades.map(trade => ({
            index: trade.index,
            symbol: trade.symbol,
            direction: trade.direction,
            net_profit: trade.net_profit,
            gross_profit: trade.gross_profit,
            commission: trade.commission,
            open_price: trade.open_price,
            close_price: trade.close_price,
            open_qty: trade.open_qty,
            close_qty: trade.close_qty,
            holding_time: trade.holding_time,
            entry_reason: trade.entry_reason,
            exit_reason: trade.exit_reason,
            trade_type: trade.trade_type,
            open_datetime: trade.open_datetime,
            close_datetime: trade.close_datetime,
            side: trade.side,
            nth_trade: trade.nth_trade,
            rating: trade.rating,
            session: trade.session,
            point_profit_per_lot: trade.point_profit_per_lot,
            total_points: trade.total_points,
            open_order_type: trade.open_order_type,
            close_order_type: trade.close_order_type,
            max_floating_profit_points: trade.max_floating_profit_points,
            max_floating_profit_dollars: trade.max_floating_profit_dollars,
            max_floating_loss_points: trade.max_floating_loss_points,
            max_floating_loss_dollars: trade.max_floating_loss_dollars,
            stop_loss_price: trade.stop_loss_price,
            take_profit_price: trade.take_profit_price,
            stop_loss_reason: trade.stop_loss_reason,
            take_profit_reason: trade.take_profit_reason,
            open_rrr: trade.open_rrr,
            close_rrr: trade.close_rrr,
            fwr: trade.fwr,
            evaluation: trade.evaluation
        }));
    });
    
    return {
        labels: labels,
        datasets: [{
            label: ew_getFieldDisplayName(yField),
            data: dataValues,
            backgroundColor: ew_getAdvancedChartColors(labels.length, config.chartType, config.colorScheme, dataValues),
            borderColor: ew_getAdvancedChartColors(labels.length, config.chartType, config.colorScheme, dataValues, true),
            borderWidth: config.chartType === 'pie' || config.chartType === 'doughnut' ? 0 : 2
        }],
        formattedValues: formattedValues,
        tradeDetails: tradeDetails,
        fullTradeDetails: fullTradeDetails,
        tradeCounts: labelValuePairs.map(pair => pair.count)
    };
}

// 获取高级字段值
function ew_getAdvancedFieldValue(trade, field) {
    switch (field) {
        case 'session':
            // 判断交易时段
            if (trade.open_datetime) {
                const hour = new Date(trade.open_datetime).getHours();
                if (hour >= 21 || hour < 6) return 'ETH';
                return 'RTH';
            }
            return '未知';
        case 'holding_time_minutes':
            if (trade.holding_time) {
                const parts = trade.holding_time.split(':');
                return parseInt(parts[0]) * 60 + parseInt(parts[1]);
            }
            return 0;
        default:
            return ew_getFieldValue(trade, field);
    }
}

// 高级数值聚合
function ew_aggregateAdvancedValue(trades, field, aggregation) {
    if (!trades || trades.length === 0) return 0;
    
    console.log('聚合字段:', field, '聚合方式:', aggregation, '交易数量:', trades.length);
    
    let values = [];
    
    switch (field) {
        case 'count':
            return trades.length;
            
        case 'average_win':
            values = trades.filter(t => (t.net_profit || 0) > 0).map(t => t.net_profit || 0);
            break;
            
        case 'average_loss':
            values = trades.filter(t => (t.net_profit || 0) < 0).map(t => Math.abs(t.net_profit || 0));
            break;
            
        case 'holding_time_minutes':
            values = trades.map(t => ew_getAdvancedFieldValue(t, 'holding_time_minutes'));
            break;
            
        case 'win_rate':
            const winCount = trades.filter(t => (t.net_profit || 0) > 0).length;
            return (winCount / trades.length * 100);
            
        case 'profit_factor':
            const grossProfit = trades.filter(t => (t.net_profit || 0) > 0).reduce((sum, t) => sum + (t.net_profit || 0), 0);
            const grossLoss = Math.abs(trades.filter(t => (t.net_profit || 0) < 0).reduce((sum, t) => sum + (t.net_profit || 0), 0));
            return grossLoss === 0 ? (grossProfit > 0 ? 999 : 0) : grossProfit / grossLoss;
            
        // 处理所有数值型字段 (按数据库模型完整列出)
        case 'index':
        case 'nth_trade':
        case 'rating':
        case 'open_price':
        case 'close_price':
        case 'open_qty':
        case 'close_qty':
        case 'point_profit_per_lot':
        case 'total_points':
        case 'gross_profit':
        case 'net_profit':
        case 'commission':
        case 'max_floating_profit_points':
        case 'max_floating_profit_dollars':
        case 'max_floating_loss_points':
        case 'max_floating_loss_dollars':
        case 'stop_loss_price':
        case 'take_profit_price':
        case 'open_rrr':
        case 'close_rrr':
        case 'fwr':
        case 'actual_risk':
        case 'extend':
        case 'prr':
            values = trades.map(t => {
                const val = t[field];
                const numVal = (val !== null && val !== undefined && val !== '' && val !== '未知') ? Number(val) : 0;
                return isNaN(numVal) ? 0 : numVal;
            });
            break;
            
        default:
            // 对于未特别处理的字段，尝试作为数值处理
            values = trades.map(t => {
                const val = t[field];
                const numVal = (val !== null && val !== undefined && val !== '' && val !== '未知') ? Number(val) : 0;
                return isNaN(numVal) ? 0 : numVal;
            });
    }
    
    if (values.length === 0) return 0;
    
    console.log('提取的数值:', values.slice(0, 5), '...(共', values.length, '个)');
    
    let result = 0;
    switch (aggregation) {
        case 'sum':
            result = values.reduce((sum, val) => sum + val, 0);
            break;
        case 'avg':
            result = values.reduce((sum, val) => sum + val, 0) / values.length;
            break;
        case 'max':
            result = Math.max(...values);
            break;
        case 'min':
            result = Math.min(...values);
            break;
        case 'count':
            result = values.length;
            break;
        case 'median':
            values.sort((a, b) => a - b);
            const mid = Math.floor(values.length / 2);
            result = values.length % 2 === 0 ? (values[mid - 1] + values[mid]) / 2 : values[mid];
            break;
        case 'stddev':
            const mean = values.reduce((sum, val) => sum + val, 0) / values.length;
            const variance = values.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) / values.length;
            result = Math.sqrt(variance);
            break;
        default:
            result = values.reduce((sum, val) => sum + val, 0);
    }
    
    console.log('聚合结果:', result);
    return result;
}

// 数值格式化
function ew_formatValue(value, format) {
    switch (format) {
        case 'currency':
            return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(value);
        case 'percentage':
            return (value).toFixed(1) + '%';
        case 'decimal':
            return value.toFixed(2);
        case 'integer':
            return Math.round(value).toString();
        default:
            return value.toFixed(2);
    }
}

// 高级颜色方案
function ew_getAdvancedChartColors(count, chartType, colorScheme, values = [], border = false) {
    let colors = [];
    
    switch (colorScheme) {
        case 'profit_loss':
            colors = values.map(value => {
                if (value > 0) return border ? '#28a745' : 'rgba(40, 167, 69, 0.8)';
                if (value < 0) return border ? '#dc3545' : 'rgba(220, 53, 69, 0.8)';
                return border ? '#6c757d' : 'rgba(108, 117, 125, 0.8)';
            });
            break;
        case 'performance':
            const maxValue = Math.max(...values);
            const minValue = Math.min(...values);
            const range = maxValue - minValue;
            colors = values.map(value => {
                const ratio = range === 0 ? 0.5 : (value - minValue) / range;
                const red = Math.round(255 * (1 - ratio));
                const green = Math.round(255 * ratio);
                return border ? `rgb(${red}, ${green}, 0)` : `rgba(${red}, ${green}, 0, 0.8)`;
            });
            break;
        case 'rainbow':
            colors = Array.from({length: count}, (_, i) => {
                const hue = (i * 360 / count) % 360;
                return border ? `hsl(${hue}, 70%, 50%)` : `hsla(${hue}, 70%, 50%, 0.8)`;
            });
            break;
        case 'monochrome':
            colors = Array.from({length: count}, (_, i) => {
                const lightness = 30 + (i * 40 / count);
                return border ? `hsl(220, 70%, ${lightness}%)` : `hsla(220, 70%, ${lightness}%, 0.8)`;
            });
            break;
        default:
            return ew_getChartColors(count, chartType, border);
    }
    
    return colors;
}

// 处理交易数据（保持向后兼容）
function ew_processChartData(trades, config) {
    return ew_processAdvancedChartData(trades, config);
}

// 获取字段值
function ew_getFieldValue(trade, field) {
    switch (field) {
        // 基本信息
        case 'index':
            return trade.index || '未知';
        case 'trade_id':
            return trade.trade_id || '未知';
        case 'symbol':
            return trade.symbol || '未知';
        case 'direction':
            return trade.direction || '未知';
        case 'side':
            return trade.side || '未知';
        case 'trade_type':
            return trade.trade_type || '未知';
        case 'session':
            return trade.session || '未知';
        case 'nth_trade':
            return trade.nth_trade || '未知';
        
        // 价格和数量相关
        case 'open_price':
            return trade.open_price || '未知';
        case 'close_price':
            return trade.close_price || '未知';
        case 'open_qty':
            return trade.open_qty || '未知';
        case 'close_qty':
            return trade.close_qty || '未知';
        
        // 时间相关
        case 'open_datetime':
            return trade.open_datetime ? new Date(trade.open_datetime).toISOString() : '未知';
        case 'close_datetime':
            return trade.close_datetime ? new Date(trade.close_datetime).toISOString() : '未知';
        case 'holding_time':
            return trade.holding_time || '未知';
        case 'open_date':
            return trade.open_datetime ? new Date(trade.open_datetime).toISOString().split('T')[0] : '未知';
        case 'close_date':
            return trade.close_datetime ? new Date(trade.close_datetime).toISOString().split('T')[0] : '未知';
        case 'month':
            return trade.open_datetime ? new Date(trade.open_datetime).toISOString().slice(0, 7) : '未知';
        case 'weekday':
            const days = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
            return trade.open_datetime ? days[new Date(trade.open_datetime).getDay()] : '未知';
        case 'hour':
            return trade.open_datetime ? new Date(trade.open_datetime).getHours() + ':00' : '未知';
        
        // 订单类型
        case 'open_order_type':
            return trade.open_order_type || '未知';
        case 'close_order_type':
            return trade.close_order_type || '未知';
        
        // 盈亏相关
        case 'net_profit':
            return trade.net_profit || 0;
        case 'gross_profit':
            return trade.gross_profit || 0;
        case 'commission':
            return trade.commission || 0;
        case 'point_profit_per_lot':
            return trade.point_profit_per_lot || 0;
        case 'total_points':
            return trade.total_points || 0;
        
        // 浮盈浮亏
        case 'max_floating_profit_points':
            return trade.max_floating_profit_points || 0;
        case 'max_floating_profit_dollars':
            return trade.max_floating_profit_dollars || 0;
        case 'max_floating_loss_points':
            return trade.max_floating_loss_points || 0;
        case 'max_floating_loss_dollars':
            return trade.max_floating_loss_dollars || 0;
        
        // 交易原因
        case 'entry_reason':
            return trade.entry_reason || '未知';
        case 'exit_reason':
            return trade.exit_reason || '未知';
        
        // 止损止盈
        case 'stop_loss_price':
            return trade.stop_loss_price || '未知';
        case 'stop_loss_reason':
            return trade.stop_loss_reason || '未知';
        case 'take_profit_price':
            return trade.take_profit_price || '未知';
        case 'take_profit_reason':
            return trade.take_profit_reason || '未知';
        
        // 评价指标
        case 'rating':
            return trade.rating || '未知';
        case 'evaluation':
            return trade.evaluation || '未知';
        case 'open_rrr':
            return trade.open_rrr || 0;
        case 'close_rrr':
            return trade.close_rrr || 0;
        case 'fwr':
            return trade.fwr || 0;
        case 'actual_risk':
            return trade.actual_risk || 0;
        case 'extend':
            return trade.extend || 0;
        case 'prr':
            return trade.prr || 0;
        
        // 默认
        default:
            return trade[field] || '未知';
    }
}

// 聚合值
function ew_aggregateValue(trades, field, aggregation) {
    if (!trades || trades.length === 0) return 0;
    
    let values = [];
    
    switch (field) {
        case 'count':
            return trades.length;
        case 'net_profit':
            values = trades.map(t => t.net_profit || 0);
            break;
        case 'gross_profit':
            values = trades.filter(t => (t.net_profit || 0) > 0).map(t => t.net_profit || 0);
            break;
        case 'gross_loss':
            values = trades.filter(t => (t.net_profit || 0) < 0).map(t => t.net_profit || 0);
            break;
        case 'win_rate':
            const winCount = trades.filter(t => (t.net_profit || 0) > 0).length;
            return (winCount / trades.length * 100);
        case 'profit_factor':
            const grossProfit = trades.filter(t => (t.net_profit || 0) > 0).reduce((sum, t) => sum + (t.net_profit || 0), 0);
            const grossLoss = Math.abs(trades.filter(t => (t.net_profit || 0) < 0).reduce((sum, t) => sum + (t.net_profit || 0), 0));
            return grossLoss === 0 ? (grossProfit > 0 ? 999 : 0) : grossProfit / grossLoss;
        case 'average_win':
            values = trades.filter(t => (t.net_profit || 0) > 0).map(t => t.net_profit || 0);
            break;
        case 'average_loss':
            values = trades.filter(t => (t.net_profit || 0) < 0).map(t => Math.abs(t.net_profit || 0));
            break;
        
        // 数值型字段 (完整的数据库字段列表)
        case 'index':
        case 'nth_trade':
        case 'rating':
        case 'open_price':
        case 'close_price':
        case 'open_qty':
        case 'close_qty':
        case 'point_profit_per_lot':
        case 'total_points':
        case 'gross_profit':
        case 'commission':
        case 'max_floating_profit_points':
        case 'max_floating_profit_dollars':
        case 'max_floating_loss_points':
        case 'max_floating_loss_dollars':
        case 'stop_loss_price':
        case 'take_profit_price':
        case 'open_rrr':
        case 'close_rrr':
        case 'fwr':
        case 'actual_risk':
        case 'extend':
        case 'prr':
            values = trades.map(t => {
                const val = t[field];
                return (val !== null && val !== undefined && val !== '') ? Number(val) : 0;
            });
            break;
            
        default:
            values = trades.map(t => t[field] || 0);
    }
    
    if (values.length === 0) return 0;
    
    switch (aggregation) {
        case 'sum':
            return values.reduce((sum, val) => sum + val, 0);
        case 'avg':
            return values.reduce((sum, val) => sum + val, 0) / values.length;
        case 'max':
            return Math.max(...values);
        case 'min':
            return Math.min(...values);
        case 'count':
            return values.length;
        case 'median':
            const sortedValues = values.sort((a, b) => a - b);
            const mid = Math.floor(sortedValues.length / 2);
            return sortedValues.length % 2 === 0 ? (sortedValues[mid - 1] + sortedValues[mid]) / 2 : sortedValues[mid];
        case 'stddev':
            const mean = values.reduce((sum, val) => sum + val, 0) / values.length;
            const variance = values.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) / values.length;
            return Math.sqrt(variance);
        default:
            return values.reduce((sum, val) => sum + val, 0);
    }
}

// 获取字段显示名称
function ew_getFieldDisplayName(field) {
    const names = {
        // 基本信息
        'index': '序号',
        'trade_id': '交易ID',
        'symbol': '品种',
        'direction': '方向',
        'side': '边',
        'trade_type': '交易类型',
        'session': '交易时段',
        'nth_trade': '第N笔交易',
        
        // 价格和数量
        'open_price': '开仓价格',
        'close_price': '平仓价格',
        'open_qty': '开仓手数',
        'close_qty': '平仓手数',
        
        // 时间相关
        'open_datetime': '开仓时间',
        'close_datetime': '平仓时间',
        'holding_time': '持仓时间',
        'holding_time_minutes': '持仓时间(分钟)',
        'holding_time_avg': '平均持仓时间',
        'open_date': '开仓日期',
        'close_date': '平仓日期',
        'month': '月份',
        'weekday': '星期',
        'hour': '小时',
        
        // 订单类型
        'open_order_type': '开仓订单类型',
        'close_order_type': '平仓订单类型',
        
        // 盈亏相关
        'net_profit': '净利润',
        'gross_profit': '总利润',
        'gross_loss': '总亏损',
        'avg_profit': '平均利润',
        'commission': '手续费',
        'point_profit_per_lot': '每手点数盈亏',
        'total_points': '总点数',
        
        // 浮盈浮亏
        'max_floating_profit_points': '最大浮盈点数',
        'max_floating_profit_dollars': '最大浮盈金额',
        'max_floating_loss_points': '最大浮亏点数',
        'max_floating_loss_dollars': '最大浮亏金额',
        
        // 交易原因
        'entry_reason': '入场理由',
        'exit_reason': '出场理由',
        
        // 止损止盈
        'stop_loss_price': '止损价格',
        'stop_loss_reason': '止损理由',
        'take_profit_price': '止盈价格',
        'take_profit_reason': '止盈理由',
        
        // 评价指标
        'rating': '交易评分',
        'evaluation': '交易评价',
        'open_rrr': '开仓RRR',
        'close_rrr': '平仓RRR',
        'fwr': 'FWR比率',
        
        // 统计指标
        'count': '交易数量',
        'win_rate': '胜率(%)',
        'profit_factor': '盈亏比',
        'max_profit': '最大利润',
        'max_loss': '最大亏损',
        'average_win': '平均盈利',
        'average_loss': '平均亏损'
    };
    return names[field] || field;
}

// 获取图表颜色
function ew_getChartColors(count, chartType, border = false) {
    const colors = [
        '#FF6384', '#36A2EB', '#FFCE56', '#4BC0C0', '#9966FF',
        '#FF9F40', '#FF6384', '#C9CBCF', '#4BC0C0', '#FF6384'
    ];
    
    if (chartType === 'pie' || chartType === 'doughnut') {
        return colors.slice(0, count);
    }
    
    if (border) {
        return colors.slice(0, count).map(color => color.replace('0.2', '1'));
    }
    
    return colors.slice(0, count).map(color => color.replace('FF', '80'));
}

// 从统计数据中模拟交易数据（临时方案）
function ew_simulateTradesFromStats(stats) {
    const trades = [];
    
    // 从符号统计中生成模拟数据
    if (stats.symbols) {
        Object.keys(stats.symbols).forEach(symbol => {
            const symbolStats = stats.symbols[symbol];
            const count = symbolStats.total_trades || 0;
            const avgProfit = symbolStats.avg_profit || 0;
            
            for (let i = 0; i < count; i++) {
                trades.push({
                    symbol: symbol,
                    net_profit: avgProfit + (Math.random() - 0.5) * avgProfit * 0.5,
                    trade_type: 'Scalp',
                    direction: Math.random() > 0.5 ? 'Long' : 'Short',
                    entry_reason: 'breakout',
                    exit_reason: '符合预期-盈利离场',
                    side: 'Right',
                    open_datetime: new Date(Date.now() - Math.random() * 90 * 24 * 60 * 60 * 1000).toISOString(),
                    close_datetime: new Date(Date.now() - Math.random() * 90 * 24 * 60 * 60 * 1000).toISOString()
                });
            }
        });
    }
    
    return trades;
}

// 获取图表配置
function ew_getChartConfig() {
    // 获取过滤条件
    const filters = [];
    const filterElements = document.querySelectorAll('[id^="chartFilter_"]');
    filterElements.forEach(element => {
        const fieldElement = element.querySelector('.chart-filter-field');
        const operatorElement = element.querySelector('.chart-filter-operator');
        const valueElement = element.querySelector('.chart-filter-value');
        const logicElement = element.querySelector('.chart-filter-logic');
        
        if (fieldElement && operatorElement && valueElement && logicElement) {
            const field = fieldElement.value;
            const operator = operatorElement.value;
            const value = valueElement.value;
            const logic = logicElement.value;
            
            if (field && operator && (value || operator === 'is_empty' || operator === 'is_not_empty')) {
                filters.push({ field, operator, value, logic });
            }
        }
    });
    
    return {
        // 过滤器
        filters: filters,
        
        // 图表类型
        chartType: document.getElementById('chartType')?.value || 'bar',
        
        // X轴配置
        xField: document.getElementById('xField')?.value || '',
        xSort: document.getElementById('xSort')?.value || 'value_desc',
        xIncludeEmpty: document.getElementById('xIncludeEmpty')?.checked || false,
        xMaxItems: parseInt(document.getElementById('xMaxItems')?.value || '0'),
        
        // 分段基数配置
        xEnableBinning: document.getElementById('xEnableBinning')?.checked || false,
        xBinningMethod: document.getElementById('xBinningMethod')?.value || 'auto',
        xBinningValue: parseFloat(document.getElementById('xBinningValue')?.value || '10'),
        xBinningFormat: document.getElementById('xBinningFormat')?.value || 'range',
        xBinningIncludeEmpty: document.getElementById('xBinningIncludeEmpty')?.checked || false,
        xBinningRoundValues: document.getElementById('xBinningRoundValues')?.checked || false,
        
        // Y轴配置
        yField: document.getElementById('yField')?.value || '',
        aggregation: document.getElementById('aggregation')?.value || 'sum',
        colorScheme: document.getElementById('colorScheme')?.value || 'default',
        valueFormat: document.getElementById('valueFormat')?.value || 'auto',
        
        // 高级选项
        showDataLabels: document.getElementById('showDataLabels')?.checked !== false,
        showLegend: document.getElementById('showLegend')?.checked !== false,
        enableAnimation: document.getElementById('enableAnimation')?.checked !== false,
        chartTitle: document.getElementById('chartTitle')?.value || '',
        chartHeight: parseInt(document.getElementById('chartHeight')?.value || '400')
    };
}

// 获取过滤后的交易数据
async function ew_getFilteredTradeData(config) {
    try {
        // 构建过滤参数
        const filterParams = new URLSearchParams();
        
        // 添加过滤条件
        config.filters.forEach((filter, index) => {
            filterParams.append(`filter_${index}_field`, filter.field);
            filterParams.append(`filter_${index}_operator`, filter.operator);
            filterParams.append(`filter_${index}_value`, filter.value);
            filterParams.append(`filter_${index}_logic`, filter.logic);
        });
        
        // 获取数据
        const response = await fetch(`/statistics/chart_data?${filterParams.toString()}`);
        if (!response.ok) {
            throw new Error(`HTTP错误: ${response.status}`);
        }
        
        const data = await response.json();
        return {
            records: data.trades || [],
            total: data.total || 0
        };
        
    } catch (error) {
        console.error('获取数据失败:', error);
        // fallback到模拟数据
        return {
            records: ew_simulateTradesFromStats(window.ewStats || {}),
            total: 0
        };
    }
}

// 应用数据过滤器
function ew_applyFilters(records, filters) {
    if (!filters || filters.length === 0) {
        return records;
    }
    
    return records.filter(record => {
        let result = true;
        let lastLogic = 'and';
        
        for (const filter of filters) {
            const fieldValue = record[filter.field];
            let conditionResult = false;
            
            switch (filter.operator) {
                case 'equals':
                    conditionResult = String(fieldValue) === String(filter.value);
                    break;
                case 'not_equals':
                    conditionResult = String(fieldValue) !== String(filter.value);
                    break;
                case 'contains':
                    conditionResult = String(fieldValue).toLowerCase().includes(String(filter.value).toLowerCase());
                    break;
                case 'not_contains':
                    conditionResult = !String(fieldValue).toLowerCase().includes(String(filter.value).toLowerCase());
                    break;
                case 'greater_than':
                    if (ew_isDateTimeField(filter.field)) {
                        conditionResult = new Date(fieldValue) > new Date(filter.value);
                    } else {
                        conditionResult = Number(fieldValue) > Number(filter.value);
                    }
                    break;
                case 'less_than':
                    if (ew_isDateTimeField(filter.field)) {
                        conditionResult = new Date(fieldValue) < new Date(filter.value);
                    } else {
                        conditionResult = Number(fieldValue) < Number(filter.value);
                    }
                    break;
                case 'greater_than_or_equal':
                    if (ew_isDateTimeField(filter.field)) {
                        conditionResult = new Date(fieldValue) >= new Date(filter.value);
                    } else {
                        conditionResult = Number(fieldValue) >= Number(filter.value);
                    }
                    break;
                case 'less_than_or_equal':
                    if (ew_isDateTimeField(filter.field)) {
                        conditionResult = new Date(fieldValue) <= new Date(filter.value);
                    } else {
                        conditionResult = Number(fieldValue) <= Number(filter.value);
                    }
                    break;
                case 'is_empty':
                    conditionResult = !fieldValue || fieldValue === '' || fieldValue === null || fieldValue === undefined;
                    break;
                case 'is_not_empty':
                    conditionResult = fieldValue && fieldValue !== '' && fieldValue !== null && fieldValue !== undefined;
                    break;
            }
            
            if (lastLogic === 'and') {
                result = result && conditionResult;
            } else {
                result = result || conditionResult;
            }
            
            lastLogic = filter.logic;
        }
        
        return result;
    });
}

// 更新自定义图表
async function ew_updateCustomChart() {
    const config = ew_getChartConfig();
    
    // 显示加载中
    const noDataMessage = document.getElementById('noDataMessage');
    noDataMessage.innerHTML = '<i class="fas fa-spinner fa-spin fa-3x mb-3"></i><h5>正在生成图表...</h5>';
    noDataMessage.style.display = 'block';
    
    try {
        // 获取过滤后的数据
        const filteredData = await ew_getFilteredTradeData(config);
        let trades = filteredData.records;
        
        console.log("config",config);
        console.log("filteredData",filteredData);
        console.log("trades",trades);

        // 应用本地过滤器
        trades = ew_applyFilters(trades, config.filters);
        
        if (!trades || trades.length === 0) {
            noDataMessage.innerHTML = '<i class="fas fa-chart-bar fa-3x mb-3"></i><h5>暂无数据</h5><p>当前过滤条件下没有找到数据</p>';
            noDataMessage.style.display = 'block';
            document.getElementById('customChartContainer').style.display = 'none';
            if (customChart) {
                customChart.destroy();
                customChart = null;
            }
            return;
        }
        
        // 处理数据
        const chartData = ew_processAdvancedChartData(trades, config);
        
        if (!chartData.labels || chartData.labels.length === 0) {
            noDataMessage.innerHTML = '<i class="fas fa-chart-bar fa-3x mb-3"></i><h5>暂无数据</h5><p>处理后的数据为空</p>';
            noDataMessage.style.display = 'block';
            document.getElementById('customChartContainer').style.display = 'none';
            if (customChart) {
                customChart.destroy();
                customChart = null;
            }
            return;
        }
        
        // 隐藏无数据提示
        noDataMessage.style.display = 'none';
        
        // 显示图表容器
        const chartContainer = document.getElementById('customChartContainer');
        chartContainer.style.display = 'block';
        
        // 更新图表
        const canvas = document.getElementById('customChart');
        const ctx = canvas.getContext('2d');
        
        // 设置图表容器高度
        chartContainer.style.height = config.chartHeight + 'px';
        
        if (customChart) {
            customChart.destroy();
        }
        
        // 创建高级图表配置
        const chartConfig = {
            type: config.chartType,
            data: chartData,
                            options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    layout: {
                        padding: 10
                    },
                    animation: {
                        duration: config.enableAnimation ? 1000 : 0
                    },
                plugins: {
                    title: {
                        display: true,
                        text: config.chartTitle || `${ew_getFieldDisplayName(config.xField)} vs ${ew_getFieldDisplayName(config.yField)}`,
                        font: {
                            size: 16,
                            weight: 'bold'
                        }
                    },
                    legend: {
                        display: config.showLegend && (config.chartType === 'pie' || config.chartType === 'doughnut' || chartData.labels.length > 1),
                        position: config.chartType === 'pie' || config.chartType === 'doughnut' ? 'right' : 'top'
                    },
                    tooltip: {
                        callbacks: {
                            title: function(context) {
                                const dataIndex = context[0].dataIndex;
                                const xLabel = chartData.labels[dataIndex];
                                const tradeCount = chartData.tradeCounts ? chartData.tradeCounts[dataIndex] : 0;
                                return `${xLabel} (${tradeCount} 笔交易)`;
                            },
                            label: function(context) {
                                const label = context.dataset.label || '';
                                let value = context.parsed.y || context.parsed;
                                
                                // 使用格式化的值
                                if (chartData.formattedValues && chartData.formattedValues[context.dataIndex]) {
                                    value = chartData.formattedValues[context.dataIndex];
                                } else {
                                    value = ew_formatValue(value, config.valueFormat);
                                }
                                
                                return label + ': ' + value;
                            },
                            afterLabel: function(context) {
                                const dataIndex = context.dataIndex;
                                const trades = chartData.tradeDetails ? chartData.tradeDetails[dataIndex] : [];
                                
                                if (!trades || trades.length === 0) {
                                    return '';
                                }
                                
                                // 简单显示前几笔交易的基本信息
                                const lines = [''];
                                const displayCount = Math.min(trades.length, 5);
                                
                                trades.slice(0, displayCount).forEach((trade, index) => {
                                    const profit = parseFloat(trade.net_profit || 0);
                                    const profitText = profit >= 0 ? `+${profit.toFixed(2)}` : `${profit.toFixed(2)}`;
                                    const profitColor = profit >= 0 ? '🟢' : '🔴';
                                    
                                    lines.push(`${profitColor} ${trade.symbol || ''} ${trade.direction || ''} ${profitText}`);
                                });
                                
                                // 如果有更多交易，显示总计信息
                                if (trades.length > displayCount) {
                                    const totalProfit = trades.reduce((sum, t) => sum + (parseFloat(t.net_profit) || 0), 0);
                                    const totalProfitText = totalProfit >= 0 ? `+${totalProfit.toFixed(2)}` : `${totalProfit.toFixed(2)}`;
                                    const totalIcon = totalProfit >= 0 ? '🟢' : '🔴';
                                    lines.push(`... 还有 ${trades.length - displayCount} 笔交易`);
                                    lines.push(`${totalIcon} 总计: ${totalProfitText}`);
                                }
                                
                                return lines;
                            }
                        },
                        displayColors: false,
                        backgroundColor: 'rgba(0, 0, 0, 0.8)',
                        titleColor: '#fff',
                        bodyColor: '#fff',
                        borderColor: '#333',
                        borderWidth: 1,
                        padding: 8,
                        bodySpacing: 2,
                        titleSpacing: 4,
                        footerSpacing: 4,
                        cornerRadius: 4,
                        maxWidth: 300,
                        bodyFont: {
                            size: 12
                        },
                        titleFont: {
                            size: 14,
                            weight: 'bold'
                        }
                    }
                },
                scales: ew_getAdvancedScalesConfig(config, chartData),
                onClick: function(event, elements) {
                    if (elements.length > 0) {
                        const dataIndex = elements[0].index;
                        const trades = chartData.fullTradeDetails ? chartData.fullTradeDetails[dataIndex] : [];
                        const label = chartData.labels[dataIndex];
                        const tradeCount = chartData.tradeCounts ? chartData.tradeCounts[dataIndex] : 0;
                        
                        if (trades && trades.length > 0) {
                            ew_showTradeDetailsModal(label, trades, tradeCount);
                        }
                    }
                }
            }
        };
        
        // 添加数据标签插件支持
        if (config.showDataLabels && typeof Chart.plugins !== 'undefined') {
            chartConfig.plugins = chartConfig.plugins || {};
            chartConfig.plugins.datalabels = {
                display: true,
                color: 'black',
                font: {
                    weight: 'bold'
                },
                formatter: function(value, context) {
                    if (chartData.formattedValues && chartData.formattedValues[context.dataIndex]) {
                        return chartData.formattedValues[context.dataIndex];
                    }
                    return ew_formatValue(value, config.valueFormat);
                }
            };
        }
        
        customChart = new Chart(ctx, chartConfig);
        
        // 隐藏配置面板，显示图表
        ew_hideChartConfig();
        
        console.log('高级图表生成成功:', {
            config: config,
            chartData: chartData,
            tradesCount: trades.length
        });
        
    } catch (error) {
        console.error('更新图表失败:', error);
        noDataMessage.innerHTML = '<i class="fas fa-exclamation-triangle fa-3x mb-3"></i><h5>加载失败</h5><p>请检查网络连接后重试</p>';
        noDataMessage.style.display = 'block';
        document.getElementById('customChartContainer').style.display = 'none';
    }
}

// 获取高级坐标轴配置
function ew_getAdvancedScalesConfig(config, chartData) {
    // 饼图和环形图不需要坐标轴
    if (config.chartType === 'pie' || config.chartType === 'doughnut') {
        return {};
    }
    
    // 雷达图的特殊配置
    if (config.chartType === 'radar') {
        return {
            r: {
                beginAtZero: true,
                title: {
                    display: true,
                    text: ew_getFieldDisplayName(config.yField)
                }
            }
        };
    }
    
    // 极坐标图的特殊配置
    if (config.chartType === 'polarArea') {
        return {
            r: {
                beginAtZero: true
            }
        };
    }
    
    // 标准坐标轴配置
    return {
        x: {
            title: {
                display: true,
                text: ew_getFieldDisplayName(config.xField)
            },
            ticks: {
                maxRotation: 45,
                minRotation: 0
            }
        },
        y: {
            title: {
                display: true,
                text: ew_getFieldDisplayName(config.yField)
            },
            beginAtZero: true,
            ticks: {
                callback: function(value, index, values) {
                    return ew_formatValue(value, config.valueFormat);
                }
            }
        }
    };
}

// 判断字段是否为数值型
function ew_isNumericField(field) {
    const numericFields = [
        // Integer 类型字段
        'index', 'nth_trade', 'rating',
        
        // Float 类型字段 
        'open_price', 'close_price', 'open_qty', 'close_qty',
        'point_profit_per_lot', 'total_points', 'gross_profit', 'net_profit', 'commission',
        'max_floating_profit_points', 'max_floating_profit_dollars',
        'max_floating_loss_points', 'max_floating_loss_dollars',
        'stop_loss_price', 'take_profit_price', 'open_rrr', 'close_rrr', 'fwr',
        
        // 计算字段
        'holding_time_minutes',
        
        // 聚合统计字段
        'count', 'win_rate', 'profit_factor', 'average_win', 'average_loss'
    ];
    return numericFields.includes(field);
}

// 应用分段基数
function ew_applyBinning(value, config, allTrades) {
    // 如果值为空或非数值，返回原值
    if (value === null || value === undefined || value === '' || value === '未知' || isNaN(value)) {
        return value;
    }
    
    const numValue = Number(value);
    
    // 根据分段方式处理
    switch (config.xBinningMethod) {
        case 'fixed_size':
            return ew_createFixedSizeBin(numValue, config);
        case 'fixed_count':
            return ew_createFixedCountBin(numValue, config, allTrades);
        case 'percentile':
            return ew_createPercentileBin(numValue, config, allTrades);
        case 'auto':
            return ew_createAutoBin(numValue, config, allTrades);
        default:
            return value;
    }
}

// 固定区间大小分段
function ew_createFixedSizeBin(value, config) {
    const binSize = config.xBinningValue;
    const binIndex = Math.floor(value / binSize);
    const lowerBound = binIndex * binSize;
    const upperBound = lowerBound + binSize;
    
    if (config.xBinningRoundValues) {
        const roundedLower = Math.round(lowerBound * 100) / 100;
        const roundedUpper = Math.round(upperBound * 100) / 100;
        return ew_formatBinLabel(roundedLower, roundedUpper, config.xBinningFormat);
    }
    
    return ew_formatBinLabel(lowerBound, upperBound, config.xBinningFormat);
}

// 固定区间数量分段
function ew_createFixedCountBin(value, config, allTrades) {
    const numericValues = allTrades
        .map(trade => ew_getAdvancedFieldValue(trade, config.xField))
        .filter(v => v !== null && v !== undefined && v !== '' && v !== '未知' && !isNaN(v))
        .map(Number)
        .sort((a, b) => a - b);
    
    if (numericValues.length === 0) return value;
    
    const minValue = numericValues[0];
    const maxValue = numericValues[numericValues.length - 1];
    const range = maxValue - minValue;
    const binCount = config.xBinningValue;
    const binSize = range / binCount;
    
    const binIndex = Math.floor((value - minValue) / binSize);
    const actualBinIndex = Math.min(binIndex, binCount - 1); // 确保最大值在最后一个区间
    
    const lowerBound = minValue + actualBinIndex * binSize;
    const upperBound = minValue + (actualBinIndex + 1) * binSize;
    
    if (config.xBinningRoundValues) {
        const roundedLower = Math.round(lowerBound * 100) / 100;
        const roundedUpper = Math.round(upperBound * 100) / 100;
        return ew_formatBinLabel(roundedLower, roundedUpper, config.xBinningFormat);
    }
    
    return ew_formatBinLabel(lowerBound, upperBound, config.xBinningFormat);
}

// 百分位分段
function ew_createPercentileBin(value, config, allTrades) {
    const numericValues = allTrades
        .map(trade => ew_getAdvancedFieldValue(trade, config.xField))
        .filter(v => v !== null && v !== undefined && v !== '' && v !== '未知' && !isNaN(v))
        .map(Number)
        .sort((a, b) => a - b);
    
    if (numericValues.length === 0) return value;
    
    const percentileStep = config.xBinningValue;
    const binCount = Math.ceil(100 / percentileStep);
    
    for (let i = 0; i < binCount; i++) {
        const lowerPercentile = i * percentileStep;
        const upperPercentile = Math.min((i + 1) * percentileStep, 100);
        
        const lowerIndex = Math.floor((lowerPercentile / 100) * (numericValues.length - 1));
        const upperIndex = Math.floor((upperPercentile / 100) * (numericValues.length - 1));
        
        const lowerBound = numericValues[lowerIndex];
        const upperBound = numericValues[upperIndex];
        
        if (value >= lowerBound && (value <= upperBound || i === binCount - 1)) {
            if (config.xBinningRoundValues) {
                const roundedLower = Math.round(lowerBound * 100) / 100;
                const roundedUpper = Math.round(upperBound * 100) / 100;
                return ew_formatBinLabel(roundedLower, roundedUpper, config.xBinningFormat) + ` (P${lowerPercentile}-P${upperPercentile})`;
            }
            return ew_formatBinLabel(lowerBound, upperBound, config.xBinningFormat) + ` (P${lowerPercentile}-P${upperPercentile})`;
        }
    }
    
    return value;
}

// 自动最佳分段
function ew_createAutoBin(value, config, allTrades) {
    const numericValues = allTrades
        .map(trade => ew_getAdvancedFieldValue(trade, config.xField))
        .filter(v => v !== null && v !== undefined && v !== '' && v !== '未知' && !isNaN(v))
        .map(Number)
        .sort((a, b) => a - b);
    
    if (numericValues.length === 0) return value;
    
    const minValue = numericValues[0];
    const maxValue = numericValues[numericValues.length - 1];
    const range = maxValue - minValue;
    
    // 使用Sturges规则或Rice规则自动确定最佳区间数
    const optimalBinCount = Math.min(
        Math.ceil(Math.log2(numericValues.length) + 1), // Sturges规则
        Math.ceil(2 * Math.pow(numericValues.length, 1/3)), // Rice规则
        config.xBinningValue // 最大区间数限制
    );
    
    const binSize = range / optimalBinCount;
    const binIndex = Math.floor((value - minValue) / binSize);
    const actualBinIndex = Math.min(binIndex, optimalBinCount - 1);
    
    const lowerBound = minValue + actualBinIndex * binSize;
    const upperBound = minValue + (actualBinIndex + 1) * binSize;
    
    if (config.xBinningRoundValues) {
        const roundedLower = Math.round(lowerBound * 100) / 100;
        const roundedUpper = Math.round(upperBound * 100) / 100;
        return ew_formatBinLabel(roundedLower, roundedUpper, config.xBinningFormat);
    }
    
    return ew_formatBinLabel(lowerBound, upperBound, config.xBinningFormat);
}

// 格式化分段标签
function ew_formatBinLabel(lowerBound, upperBound, format) {
    switch (format) {
        case 'range':
            return `${lowerBound}-${upperBound}`;
        case 'center':
            return ((lowerBound + upperBound) / 2).toFixed(2);
        case 'lower':
            return lowerBound.toString();
        case 'upper':
            return upperBound.toString();
        default:
            return `${lowerBound}-${upperBound}`;
    }
}

// 图表配置管理功能
function ew_saveChartConfig() {
    const configName = document.getElementById('chartConfigName').value.trim();
    if (!configName) {
        alert('请输入配置名称');
        return;
    }
    
    // 收集当前图表配置
    const config = ew_getChartConfig();
    
    // 验证配置是否完整
    if (!config.xField || !config.yField || !config.aggregation) {
        alert('请先完成图表配置');
        return;
    }
    
    // 保存配置
    $.ajax({
        url: '/statistics/save_chart_config',
        method: 'POST',
        contentType: 'application/json',
        data: JSON.stringify({
            name: configName,
            config: config
        }),
        success: function(response) {
            if (response.success) {
                alert('图表配置保存成功！');
                document.getElementById('chartConfigName').value = '';
                ew_loadSavedChartConfigs();
                // 刷新快速配置按钮
                ew_refreshQuickConfigs();
            } else {
                alert('保存失败: ' + response.message);
            }
        },
        error: function() {
            alert('保存失败，请稍后重试');
        }
    });
}

function ew_loadSavedChartConfigs() {
    $.get('/statistics/saved_chart_configs', function(data) {
        const configs = data.configs || [];
        const select = document.getElementById('savedChartConfigs');
        
        // 清空现有选项
        select.innerHTML = '<option value="">选择已保存的配置...</option>';
        
        // 添加保存的配置
        configs.forEach(config => {
            const option = document.createElement('option');
            option.value = config.id;
            option.textContent = config.name;
            select.appendChild(option);
        });
    }).fail(function() {
        console.error('加载图表配置失败');
    });
}

function ew_loadChartConfig() {
    const configId = document.getElementById('savedChartConfigs').value;
    if (!configId) {
        alert('请选择要加载的配置');
        return;
    }
    
    $.get('/statistics/saved_chart_configs', function(data) {
        const configs = data.configs || [];
        const selectedConfig = configs.find(c => c.id == configId);
        
        if (!selectedConfig) {
            alert('未找到指定的配置');
            return;
        }
        
        // 应用配置到界面
        ew_applyChartConfig(selectedConfig.config);
        alert('配置加载成功！');
        
    }).fail(function() {
        alert('加载配置失败，请稍后重试');
    });
}

function ew_applyChartConfig(config) {
    // 基础配置
    const xFieldEl = document.getElementById('xField');
    if (xFieldEl) {
        xFieldEl.value = config.xField || '';
    }
    
    const yFieldEl = document.getElementById('yField');
    if (yFieldEl) {
        yFieldEl.value = config.yField || '';
    }
    
    const aggregationEl = document.getElementById('aggregation');
    if (aggregationEl) {
        aggregationEl.value = config.aggregation || 'sum';
    }
    
    const chartTypeEl = document.getElementById('chartType');
    if (chartTypeEl) {
        chartTypeEl.value = config.chartType || 'bar';
    }
    
    const colorSchemeEl = document.getElementById('colorScheme');
    if (colorSchemeEl) {
        colorSchemeEl.value = config.colorScheme || 'default';
    }
    
    // 排序和限制
    const xSortEl = document.getElementById('xSort');
    if (xSortEl) xSortEl.value = config.xSort || 'value_desc';
    
    const xMaxItemsEl = document.getElementById('xMaxItems');
    if (xMaxItemsEl) xMaxItemsEl.value = config.xMaxItems || 0;
    
    const xIncludeEmptyEl = document.getElementById('xIncludeEmpty');
    if (xIncludeEmptyEl) xIncludeEmptyEl.checked = config.xIncludeEmpty || false;
    
    // 分段设置
    const xEnableBinningEl = document.getElementById('xEnableBinning');
    if (xEnableBinningEl) xEnableBinningEl.checked = config.xEnableBinning || false;
    
    const xBinningMethodEl = document.getElementById('xBinningMethod');
    if (xBinningMethodEl) xBinningMethodEl.value = config.xBinningMethod || 'auto';
    
    // 检查分段值相关的元素是否存在
    const xBinningValueElement = document.getElementById('xBinningValue');
    if (xBinningValueElement) {
        xBinningValueElement.value = config.xBinningValue || 10;
    }
    
    const xBinningFormatElement = document.getElementById('xBinningFormat');
    if (xBinningFormatElement) {
        xBinningFormatElement.value = config.xBinningFormat || 'range';
    }
    
    const xBinningIncludeEmptyElement = document.getElementById('xBinningIncludeEmpty');
    if (xBinningIncludeEmptyElement) {
        xBinningIncludeEmptyElement.checked = config.xBinningIncludeEmpty || false;
    }
    
    const xBinningRoundValuesElement = document.getElementById('xBinningRoundValues');
    if (xBinningRoundValuesElement) {
        xBinningRoundValuesElement.checked = config.xBinningRoundValues || false;
    }
    
    // 兼容旧的字段名
    const xBinSizeElement = document.getElementById('xBinSize');
    if (xBinSizeElement) {
        xBinSizeElement.value = config.xBinSize || config.xBinningValue || 10;
    }
    
    const xBinCountElement = document.getElementById('xBinCount');
    if (xBinCountElement) {
        xBinCountElement.value = config.xBinCount || config.xBinningValue || 5;
    }
    
    // 格式化
    const valueFormatEl = document.getElementById('valueFormat');
    if (valueFormatEl) valueFormatEl.value = config.valueFormat || 'auto';
    
    // 高级选项
    const showDataLabelsEl = document.getElementById('showDataLabels');
    if (showDataLabelsEl) showDataLabelsEl.checked = config.showDataLabels !== false;
    
    const showLegendEl = document.getElementById('showLegend');
    if (showLegendEl) showLegendEl.checked = config.showLegend !== false;
    
    const enableAnimationEl = document.getElementById('enableAnimation');
    if (enableAnimationEl) enableAnimationEl.checked = config.enableAnimation !== false;
    
    const chartTitleEl = document.getElementById('chartTitle');
    if (chartTitleEl) chartTitleEl.value = config.chartTitle || '';
    
    const chartHeightEl = document.getElementById('chartHeight');
    if (chartHeightEl) chartHeightEl.value = config.chartHeight || 400;
    
    // 过滤器
    if (config.filters && Array.isArray(config.filters)) {
        // 清空现有过滤器
        ew_clearChartFilters();
        
        // 应用保存的过滤器
        config.filters.forEach((filter, index) => {
            // 添加新的过滤器
            ew_addChartFilter();
        });
        
        // 使用setTimeout确保DOM元素已经创建
        setTimeout(() => {
            config.filters.forEach((filter, index) => {
                // 获取所有过滤器元素
                const filterElements = document.querySelectorAll('[id^="chartFilter_"]');
                if (filterElements.length > index) {
                    const currentFilter = filterElements[index];
                    
                    const fieldElement = currentFilter.querySelector('.chart-filter-field');
                    const operatorElement = currentFilter.querySelector('.chart-filter-operator');
                    const valueElement = currentFilter.querySelector('.chart-filter-value');
                    const logicElement = currentFilter.querySelector('.chart-filter-logic');
                    
                    if (fieldElement) {
                        fieldElement.value = filter.field || '';
                        // 更新值输入框类型（下拉框或文本框）
                        ew_updateFilterValueInput(fieldElement);
                    }
                    if (operatorElement) operatorElement.value = filter.operator || 'equals';
                    if (logicElement) logicElement.value = filter.logic || 'and';
                    
                    // 在更新字段后设置值，确保下拉框已经创建
                    setTimeout(() => {
                        const updatedValueElement = currentFilter.querySelector('.chart-filter-value');
                        if (updatedValueElement) {
                            updatedValueElement.value = filter.value || '';
                        }
                    }, 50);
                }
            });
            
            // 更新过滤器状态显示
            ew_updateChartFilterStatus();
            ew_updateChartFilterDisplay();
        }, 100);
    }
    
    // 触发分段状态显示更新
    if (xEnableBinningEl) {
        // 触发change事件以更新UI状态
        xEnableBinningEl.dispatchEvent(new Event('change'));
    }
    
    // 如果没有过滤器，直接更新状态
    if (!config.filters || config.filters.length === 0) {
        ew_updateChartFilterStatus();
        ew_updateChartFilterDisplay();
    }
}

// 加载快速配置按钮
function ew_loadQuickConfigs() {
    // 首先加载快速配置设置
    $.get('/statistics/quick_config_settings', function(response) {
        const quickConfigContainer = document.getElementById('quickConfigButtons');
        
        if (!response.success || !response.settings || response.settings.configs.length === 0) {
            quickConfigContainer.innerHTML = '<div class="text-center w-100 text-muted small">暂无快速配置</div>';
            return;
        }
        
        const quickConfigs = response.settings.configs;
        const buttonStyle = response.settings.style || 'outline';
        let html = '';
        
        quickConfigs.forEach(config => {
            const summary = ew_getChartConfigSummary(config.config);
            const buttonClass = ew_getQuickConfigButtonClass(buttonStyle);
            
            html += `
                <button type="button" class="${buttonClass} quick-config-btn" 
                        onclick="ew_applyQuickConfig(${config.id})" 
                        title="${summary}">
                    <i class="fas fa-chart-bar me-1"></i>${config.name}
                </button>
            `;
        });
        
        quickConfigContainer.innerHTML = html;
    }).fail(function() {
        // 如果获取快速配置失败，回退到原来的逻辑
        $.get('/statistics/saved_chart_configs', function(data) {
            const configs = data.configs || [];
            const quickConfigContainer = document.getElementById('quickConfigButtons');
            
            if (configs.length === 0) {
                quickConfigContainer.innerHTML = '<div class="text-center w-100 text-muted small">暂无保存的配置</div>';
                return;
            }
            
            // 取前10个配置
            const topConfigs = configs.slice(0, 10);
            let html = '';
            
            topConfigs.forEach(config => {
                const summary = ew_getChartConfigSummary(config.config);
                html += `
                    <button type="button" class="btn btn-sm btn-outline-primary quick-config-btn" 
                            onclick="ew_applyQuickConfig(${config.id})" 
                            title="${summary}">
                        <i class="fas fa-chart-bar me-1"></i>${config.name}
                    </button>
                `;
            });
            
            quickConfigContainer.innerHTML = html;
        }).fail(function() {
            const quickConfigContainer = document.getElementById('quickConfigButtons');
            quickConfigContainer.innerHTML = '<div class="text-center w-100 text-muted small">加载配置失败</div>';
        });
    });
}

// 获取快速配置按钮的CSS类
function ew_getQuickConfigButtonClass(style) {
    switch(style) {
        case 'filled':
            return 'btn btn-sm btn-primary';
        case 'rounded':
            return 'btn btn-sm btn-outline-primary rounded-pill';
        case 'outline':
        default:
            return 'btn btn-sm btn-outline-primary';
    }
}

// 恢复快速配置按钮状态
function ew_restoreQuickConfigButtons() {
    // 检查所有快速配置按钮，如果显示错误状态，则恢复正常
    const quickConfigButtons = document.querySelectorAll('.quick-config-btn');
    
    quickConfigButtons.forEach(btn => {
        const innerHTML = btn.innerHTML;
        
        // 如果按钮显示错误状态，恢复到正常状态
        if (innerHTML.includes('请先选择图表') || 
            innerHTML.includes('配置不存在') || 
            innerHTML.includes('加载失败')) {
            
            // 从onclick属性获取configId
            const onclickAttr = btn.getAttribute('onclick');
            const configIdMatch = onclickAttr ? onclickAttr.match(/ew_applyQuickConfig\((\d+)\)/) : null;
            
            if (configIdMatch) {
                const configId = parseInt(configIdMatch[1]);
                
                // 从快速配置设置中获取原始配置名称
                if (window.quickConfigSettings && window.quickConfigSettings.configs) {
                    const config = window.quickConfigSettings.configs.find(c => c.id === configId);
                    if (config) {
                        btn.innerHTML = `<i class="fas fa-chart-bar me-1"></i>${config.name}`;
                        btn.disabled = false;
                        btn.classList.remove('active');
                    }
                }
            }
        }
    });
}

// 快速应用配置
function ew_applyQuickConfig(configId) {
    // 先显示加载状态
    const btn = document.querySelector(`[onclick="ew_applyQuickConfig(${configId})"]`);
    const originalText = btn.innerHTML;
    btn.innerHTML = '<i class="fas fa-spinner fa-spin me-1"></i>应用中...';
    btn.disabled = true;
    
    // 清除其他按钮的活动状态
    document.querySelectorAll('.quick-config-btn').forEach(otherBtn => {
        if (otherBtn !== btn) {
            otherBtn.classList.remove('active');
        }
    });
    
    $.get('/statistics/saved_chart_configs', function(data) {
        const configs = data.configs || [];
        const targetConfig = configs.find(c => c.id === configId);
        
        if (targetConfig) {
            // 应用配置
            ew_applyChartConfig(targetConfig.config);
            
            // 显示成功提示
            btn.innerHTML = '<i class="fas fa-check text-success me-1"></i>已应用';
            btn.classList.add('active');
            
            // 自动更新图表
            setTimeout(() => {
                ew_updateCustomChart();
            }, 200);
            
            // 恢复按钮状态
            setTimeout(() => {
                btn.innerHTML = originalText;
                btn.disabled = false;
                btn.classList.remove('active');
            }, 2000);
        } else {
            // 配置不存在
            btn.innerHTML = '<i class="fas fa-exclamation-triangle text-warning me-1"></i>配置不存在';
            setTimeout(() => {
                btn.innerHTML = originalText;
                btn.disabled = false;
            }, 2000);
        }
    }).fail(function() {
        // 加载失败
        btn.innerHTML = '<i class="fas fa-exclamation-triangle text-danger me-1"></i>加载失败';
        setTimeout(() => {
            btn.innerHTML = originalText;
            btn.disabled = false;
        }, 2000);
    });
}

// 刷新快速配置按钮
function ew_refreshQuickConfigs() {
    const quickConfigContainer = document.getElementById('quickConfigButtons');
    quickConfigContainer.innerHTML = '<div class="text-center w-100 text-muted small"><i class="fas fa-spinner fa-spin me-1"></i>正在刷新...</div>';
    
    setTimeout(() => {
        ew_loadQuickConfigs();
        
        // 如果快速配置管理模态框正在显示，也更新其内容
        const modal = document.getElementById('quickConfigManagerModal');
        if (modal && modal.classList.contains('show')) {
            ew_loadQuickConfigSettings().then(() => {
                ew_renderQuickConfigList();
            });
        }
    }, 500);
}

function ew_showChartConfigManager() {
    $.get('/statistics/saved_chart_configs', function(data) {
        const configs = data.configs || [];
        const listContainer = document.getElementById('chartConfigList');
        
        if (configs.length === 0) {
            listContainer.innerHTML = '<p class="text-muted text-center">暂无保存的图表配置</p>';
        } else {
            let html = '';
            configs.forEach(config => {
                const configSummary = ew_getChartConfigSummary(config.config);
                html += `
                    <div class="card mb-3">
                        <div class="card-body">
                            <div class="d-flex justify-content-between align-items-start">
                                <div class="flex-grow-1">
                                    <h6 class="mb-1">${config.name}</h6>
                                    <small class="text-muted">创建时间: ${config.created_at}</small>
                                    <div class="mt-2">
                                        <small class="text-info">${configSummary}</small>
                                    </div>
                                </div>
                                <div class="d-flex gap-2">
                                    <button class="btn btn-sm btn-primary" onclick="ew_loadChartConfigById(${config.id})">
                                        <i class="fas fa-upload"></i> 加载
                                    </button>
                                    <button class="btn btn-sm btn-warning" onclick="ew_updateChartConfig(${config.id}, '${config.name}')">
                                        <i class="fas fa-edit"></i> 更新
                                    </button>
                                    <button class="btn btn-sm btn-danger" onclick="ew_deleteChartConfig(${config.id}, '${config.name}')">
                                        <i class="fas fa-trash"></i> 删除
                                    </button>
                                </div>
                            </div>
                        </div>
                    </div>
                `;
            });
            listContainer.innerHTML = html;
        }
        
        // 显示模态框
        const modal = new bootstrap.Modal(document.getElementById('chartConfigManagerModal'));
        modal.show();
    }).fail(function() {
        alert('加载图表配置失败');
    });
}

function ew_getChartConfigSummary(config) {
    const summary = [];
    
    if (config.xField && config.yField) {
        summary.push(`${ew_getFieldDisplayName(config.xField)} vs ${ew_getFieldDisplayName(config.yField)}`);
    }
    
    if (config.aggregation) {
        const aggMap = {
            'sum': '求和',
            'avg': '平均值',
            'count': '计数',
            'max': '最大值',
            'min': '最小值',
            'median': '中位数',
            'stddev': '标准差'
        };
        summary.push(`聚合: ${aggMap[config.aggregation] || config.aggregation}`);
    }
    
    if (config.chartType) {
        const typeMap = {
            'bar': '柱状图',
            'line': '折线图',
            'pie': '饼图',
            'doughnut': '环形图',
            'scatter': '散点图',
            'radar': '雷达图',
            'polarArea': '极坐标图'
        };
        summary.push(`类型: ${typeMap[config.chartType] || config.chartType}`);
    }
    
    if (config.filters && config.filters.length > 0) {
        const activeFilters = config.filters.filter(f => f.field && f.value);
        if (activeFilters.length > 0) {
            summary.push(`过滤器: ${activeFilters.length}个`);
        }
    }
    
    return summary.length > 0 ? summary.join('; ') : '无详细信息';
}

function ew_loadChartConfigById(configId) {
    document.getElementById('savedChartConfigs').value = configId;
    ew_loadChartConfig();
    
    // 关闭管理模态框
    const modal = bootstrap.Modal.getInstance(document.getElementById('chartConfigManagerModal'));
    if (modal) {
        modal.hide();
    }
}

function ew_updateChartConfig(configId, configName) {
    if (!confirm(`确定要用当前配置覆盖 "${configName}" 吗？`)) {
        return;
    }
    
    const config = ew_getChartConfig();
    
    $.ajax({
        url: '/statistics/update_chart_config',
        method: 'POST',
        contentType: 'application/json',
        data: JSON.stringify({
            id: configId,
            config: config
        }),
        success: function(response) {
            if (response.success) {
                alert('配置更新成功！');
                ew_showChartConfigManager(); // 刷新管理界面
                // 刷新快速配置按钮
                ew_refreshQuickConfigs();
            } else {
                alert('更新失败: ' + response.message);
            }
        },
        error: function() {
            alert('更新失败，请稍后重试');
        }
    });
}

function ew_deleteChartConfig(configId, configName) {
    if (!confirm(`确定要删除图表配置 "${configName}" 吗？此操作不可撤销。`)) {
        return;
    }
    
    $.ajax({
        url: '/statistics/delete_chart_config',
        method: 'POST',
        contentType: 'application/json',
        data: JSON.stringify({
            id: configId
        }),
        success: function(response) {
            if (response.success) {
                alert('配置删除成功！');
                ew_showChartConfigManager(); // 刷新管理界面
                ew_loadSavedChartConfigs(); // 刷新下拉列表
                // 刷新快速配置按钮
                ew_refreshQuickConfigs();
            } else {
                alert('删除失败: ' + response.message);
            }
        },
        error: function() {
            alert('删除失败，请稍后重试');
        }
    });
}

// 智能标签比较函数，正确处理区间标签的排序
function ew_compareLabels(labelA, labelB) {
    // 尝试提取数值进行比较
    const valueA = ew_extractNumericValue(labelA);
    const valueB = ew_extractNumericValue(labelB);
    
    // 如果都能提取到数值，按数值比较
    if (valueA !== null && valueB !== null) {
        return valueA - valueB;
    }
    
    // 否则按字符串比较
    return labelA.localeCompare(labelB);
}

// 从标签中提取数值，支持区间标签
function ew_extractNumericValue(label) {
    if (!label || typeof label !== 'string') {
        return null;
    }
    
    // 检查是否是区间标签，需要处理双短横线的情况（如"-0.85--0.51"）
    // 正则表达式解释：第一个数字 + 单短横线或双短横线 + 第二个数字
    const rangeMatch = label.match(/^(-?\d+(?:\.\d+)?)--?(-?\d+(?:\.\d+)?)$/);
    if (rangeMatch) {
        // 对于区间标签，使用下界（第一个数字）进行排序
        return parseFloat(rangeMatch[1]);
    }
    
    // 检查是否是单一数字
    const numMatch = label.match(/^-?\d+(?:\.\d+)?$/);
    if (numMatch) {
        return parseFloat(label);
    }
    
    // 尝试提取标签开头的数字
    const leadingNumMatch = label.match(/^(-?\d+(?:\.\d+)?)/);
    if (leadingNumMatch) {
        return parseFloat(leadingNumMatch[1]);
    }
    
    // 无法提取数值，返回null
    return null;
}

// ==================== 多图表系统 ====================

// 全局变量存储所有图表实例
window.chartInstances = [];
window.currentChartId = null;
window.chartIdCounter = 1;

// 初始化多图表系统
function ew_initMultiChartSystem() {
    const container = document.getElementById('multiChartContainer');
    if (!container) return;
    
    // 初始化全局变量
    if (!window.chartInstances) {
        window.chartInstances = [];
    }
    if (!window.chartIdCounter) {
        window.chartIdCounter = 1;
    }
    if (!window.currentChartId) {
        window.currentChartId = null;
    }
    
    // 尝试加载保存的图表状态
    ew_loadMultiChartState().always(() => {
        // 无论加载成功与否，都要更新显示
        ew_updateMultiChartDisplay();
    });
}

// 更新多图表显示
function ew_updateMultiChartDisplay() {
    const container = document.getElementById('multiChartContainer');
    if (!container) return;
    
    if (window.chartInstances.length === 0) {
        container.innerHTML = `
            <div class="multi-chart-empty">
                <i class="fas fa-chart-bar fa-3x mb-3"></i>
                <h5>暂无图表</h5>
                <p>点击"添加图表"按钮创建您的第一个图表</p>
            </div>
        `;
    } else {
        // 重新渲染所有图表
        ew_renderAllCharts();
    }
}

// 添加新图表
function ew_addNewChart() {
    const chartId = `chart_${window.chartIdCounter++}`;
    const chartInstance = {
        id: chartId,
        title: `图表 ${window.chartInstances.length + 1}`,
        config: ew_getDefaultChartConfig(),
        chart: null,
        data: null
    };
    
    window.chartInstances.push(chartInstance);
    
    // 只添加新图表，不重新渲染所有图表
    const container = document.getElementById('multiChartContainer');
    if (container) {
        const chartHtml = ew_createChartInstanceHtml(chartInstance);
        container.insertAdjacentHTML('beforeend', chartHtml);
    }
    
    // 更新显示状态
    ew_updateMultiChartDisplay();
    
    // 自动保存状态
    ew_autoSaveChartState();
    
    // 自动开始配置新图表
    ew_configureChart(chartId);
    
    // 自动生成一个默认图表以便用户查看效果
    setTimeout(() => {
        ew_updateSingleChart(chartId);
    }, 500);
}

// 获取默认图表配置
function ew_getDefaultChartConfig() {
    return {
        filters: [],
        chartType: 'bar',
        xField: 'symbol',
        xSort: 'value_desc',
        xIncludeEmpty: false,
        xMaxItems: 10,
        xEnableBinning: false,
        xBinningMethod: 'auto',
        xBinningValue: 10,
        xBinningFormat: 'range',
        xBinningIncludeEmpty: false,
        xBinningRoundValues: false,
        yField: 'net_profit',
        aggregation: 'sum',
        colorScheme: 'default',
        valueFormat: 'auto',
        showDataLabels: true,
        showLegend: true,
        enableAnimation: true,
        chartTitle: '',
        chartHeight: 400,
        size: 2  // 默认占2列
    };
}

// 渲染所有图表
function ew_renderAllCharts() {
    const container = document.getElementById('multiChartContainer');
    if (!container) return;
    
    // 保存现有的图表状态
    const existingCharts = {};
    window.chartInstances.forEach(instance => {
        const existingEl = document.getElementById(`chartInstance_${instance.id}`);
        if (existingEl) {
            existingCharts[instance.id] = true;
        }
    });
    
    // 清空容器
    container.innerHTML = '';
    
    // 重新渲染所有图表
    window.chartInstances.forEach(instance => {
        const chartHtml = ew_createChartInstanceHtml(instance);
        container.insertAdjacentHTML('beforeend', chartHtml);
        
        // 如果图表有数据，立即渲染图表（不延迟）
        if (instance.data && instance.config) {
            // 隐藏"暂无数据"状态
            const noDataEl = document.getElementById(`nodata_${instance.id}`);
            if (noDataEl) {
                noDataEl.style.display = 'none';
            }
            
            // 立即渲染图表
            setTimeout(() => {
                ew_renderSingleChart(instance.id);
            }, 10); // 减少延迟
        }
    });
}

// 创建图表实例HTML
function ew_createChartInstanceHtml(instance) {
    const configSummary = ew_getChartConfigSummary(instance.config);
    const size = instance.config.size || 2;
    
    return `
        <div class="chart-instance" id="chartInstance_${instance.id}" data-span="${size}">
            <div class="chart-instance-header">
                <div class="chart-instance-title">${instance.title}</div>
                <div class="d-flex align-items-center">
                    <div class="chart-size-controls me-2">
                        <div class="chart-size-btn ${size === 1 ? 'active' : ''}" 
                             onclick="ew_changeChartSize('${instance.id}', 1)" 
                             title="1列宽度">1</div>
                        <div class="chart-size-btn ${size === 2 ? 'active' : ''}" 
                             onclick="ew_changeChartSize('${instance.id}', 2)" 
                             title="2列宽度">2</div>
                        <div class="chart-size-btn ${size === 3 ? 'active' : ''}" 
                             onclick="ew_changeChartSize('${instance.id}', 3)" 
                             title="3列宽度">3</div>
                        <div class="chart-size-btn ${size === 4 ? 'active' : ''}" 
                             onclick="ew_changeChartSize('${instance.id}', 4)" 
                             title="4列宽度">4</div>
                    </div>
                    <div class="chart-instance-controls">
                        <button type="button" class="btn btn-sm btn-light" onclick="ew_configureChart('${instance.id}')" title="配置图表">
                            <i class="fas fa-cog"></i>
                        </button>
                        <button type="button" class="btn btn-sm btn-light" onclick="ew_refreshChart('${instance.id}')" title="刷新图表">
                            <i class="fas fa-sync"></i>
                        </button>
                        <button type="button" class="btn btn-sm btn-light" onclick="ew_duplicateChart('${instance.id}')" title="复制图表">
                            <i class="fas fa-copy"></i>
                        </button>
                        <button type="button" class="btn btn-sm btn-light" onclick="ew_deleteChart('${instance.id}')" title="删除图表">
                            <i class="fas fa-trash"></i>
                        </button>
                    </div>
                </div>
            </div>
            <div class="chart-instance-body">
                <div class="chart-config-summary">${configSummary}</div>
                <div class="chart-canvas-container">
                    <canvas id="canvas_${instance.id}"></canvas>
                    <div class="chart-loading" id="loading_${instance.id}" style="display:none;">
                        <i class="fas fa-spinner fa-spin fa-2x mb-2"></i>
                        <div>正在生成图表...</div>
                    </div>
                    <div class="chart-no-data" id="nodata_${instance.id}">
                        <i class="fas fa-chart-bar fa-2x mb-2"></i>
                        <div>暂无数据</div>
                        <small>请配置图表参数</small>
                    </div>
                </div>
            </div>
        </div>
    `;
}

// 配置图表
function ew_configureChart(chartId) {
    const instance = window.chartInstances.find(c => c.id === chartId);
    if (!instance) return;
    
    window.currentChartId = chartId;
    
    // 更新配置面板标题
    document.getElementById('currentChartTitle').textContent = `当前配置: ${instance.title}`;
    
    // 应用当前图表的配置到配置面板
    ew_applyChartConfig(instance.config);
    
    // 恢复快速配置按钮状态（如果之前显示了"请先选择图表"）
    ew_restoreQuickConfigButtons();
    
    // 显示配置面板
    ew_showChartConfig();
}

// 刷新特定图表
function ew_refreshChart(chartId) {
    const instance = window.chartInstances.find(c => c.id === chartId);
    if (!instance) return;
    
    ew_updateSingleChart(chartId);
}

// 复制图表
function ew_duplicateChart(chartId) {
    const instance = window.chartInstances.find(c => c.id === chartId);
    if (!instance) return;
    
    const newChartId = `chart_${window.chartIdCounter++}`;
    const newInstance = {
        id: newChartId,
        title: `${instance.title} (副本)`,
        config: JSON.parse(JSON.stringify(instance.config)), // 深拷贝配置
        chart: null,
        data: instance.data ? JSON.parse(JSON.stringify(instance.data)) : null
    };
    
    window.chartInstances.push(newInstance);
    
    // 只添加新图表，不重新渲染所有图表
    const container = document.getElementById('multiChartContainer');
    if (container) {
        const chartHtml = ew_createChartInstanceHtml(newInstance);
        container.insertAdjacentHTML('beforeend', chartHtml);
        
        // 如果有数据，立即渲染图表
        if (newInstance.data && newInstance.config) {
            // 隐藏"暂无数据"状态
            const noDataEl = document.getElementById(`nodata_${newInstance.id}`);
            if (noDataEl) {
                noDataEl.style.display = 'none';
            }
            
            // 立即渲染图表
            setTimeout(() => {
                ew_renderSingleChart(newInstance.id);
            }, 10);
        }
    }
    
    // 更新显示状态
    ew_updateMultiChartDisplay();
    
    // 自动保存状态
    ew_autoSaveChartState();
}

// 删除图表
function ew_deleteChart(chartId) {
    const instance = window.chartInstances.find(c => c.id === chartId);
    if (!instance) return;
    
    if (!confirm(`确定要删除图表 "${instance.title}" 吗？`)) return;
    
    // 销毁图表实例
    if (instance.chart) {
        instance.chart.destroy();
    }
    
    // 从数组中移除
    window.chartInstances = window.chartInstances.filter(c => c.id !== chartId);
    
    // 如果正在配置这个图表，隐藏配置面板
    if (window.currentChartId === chartId) {
        ew_hideChartConfig();
        window.currentChartId = null;
    }
    
    ew_updateMultiChartDisplay();
    
    // 自动保存状态
    ew_autoSaveChartState();
}

// 改变图表大小
function ew_changeChartSize(chartId, size) {
    const instance = window.chartInstances.find(inst => inst.id === chartId);
    if (!instance) return;
    
    // 更新配置
    instance.config.size = size;
    
    // 更新DOM元素
    const element = document.getElementById(`chartInstance_${chartId}`);
    if (element) {
        element.setAttribute('data-span', size);
        
        // 更新大小控件状态
        const sizeControls = element.querySelectorAll('.chart-size-btn');
        sizeControls.forEach((btn, index) => {
            if (index + 1 === size) {
                btn.classList.add('active');
            } else {
                btn.classList.remove('active');
            }
        });
    }
    
    // 重新渲染图表以适应新大小
    setTimeout(() => {
        if (instance.chart) {
            instance.chart.resize();
        }
    }, 100);
    
    // 自动保存状态
    ew_autoSaveChartState();
}

// 更新单个图表
async function ew_updateSingleChart(chartId) {
    const instance = window.chartInstances.find(c => c.id === chartId);
    if (!instance) return;
    
    const loadingEl = document.getElementById(`loading_${chartId}`);
    const noDataEl = document.getElementById(`nodata_${chartId}`);
    const canvas = document.getElementById(`canvas_${chartId}`);
    
    // 显示加载状态（仅在没有现有图表时显示）
    if (loadingEl && !instance.chart) {
        loadingEl.style.display = 'block';
    }
    if (noDataEl) noDataEl.style.display = 'none';
    
    try {
        // 获取过滤后的数据
        const filteredData = await ew_getFilteredTradeData(instance.config);
        let trades = filteredData.records;
        
        // 应用本地过滤器
        trades = ew_applyFilters(trades, instance.config.filters);
        
        if (!trades || trades.length === 0) {
            if (loadingEl) loadingEl.style.display = 'none';
            if (noDataEl) {
                noDataEl.style.display = 'block';
                noDataEl.innerHTML = `
                    <i class="fas fa-chart-bar fa-2x mb-2"></i>
                    <div>暂无数据</div>
                    <small>当前过滤条件下没有找到数据</small>
                `;
            }
            return;
        }
        
        // 处理数据
        const chartData = ew_processAdvancedChartData(trades, instance.config);
        
        if (!chartData.labels || chartData.labels.length === 0) {
            if (loadingEl) loadingEl.style.display = 'none';
            if (noDataEl) {
                noDataEl.style.display = 'block';
                noDataEl.innerHTML = `
                    <i class="fas fa-chart-bar fa-2x mb-2"></i>
                    <div>暂无数据</div>
                    <small>处理后的数据为空</small>
                `;
            }
            return;
        }
        
        // 存储数据
        instance.data = chartData;
        
        // 隐藏加载和无数据提示
        if (loadingEl) loadingEl.style.display = 'none';
        if (noDataEl) noDataEl.style.display = 'none';
        
        // 确保画布可见
        if (canvas) {
            canvas.style.display = 'block';
        }
        
        // 渲染图表
        ew_renderSingleChart(chartId);
        
    } catch (error) {
        console.error('生成图表失败:', error);
        if (loadingEl) loadingEl.style.display = 'none';
        if (noDataEl) {
            noDataEl.style.display = 'block';
            noDataEl.innerHTML = `
                <i class="fas fa-exclamation-triangle fa-2x mb-2 text-warning"></i>
                <div>图表生成失败</div>
                <small>请检查配置或稍后重试</small>
            `;
        }
    }
}

// 渲染单个图表
function ew_renderSingleChart(chartId) {
    const instance = window.chartInstances.find(c => c.id === chartId);
    if (!instance || !instance.data) return;
    
    const canvas = document.getElementById(`canvas_${chartId}`);
    if (!canvas) return;
    
    const ctx = canvas.getContext('2d');
    
    // 销毁已存在的图表
    if (instance.chart) {
        instance.chart.destroy();
        instance.chart = null;
    }
    
    // 设置画布高度
    const container = canvas.parentElement;
    if (container) {
        container.style.height = `${instance.config.chartHeight || 400}px`;
    }
    
    // 创建新图表
    const chartOptions = ew_getAdvancedScalesConfig(instance.config, instance.data);
    
    // 确保图表响应式并占满容器宽度
    chartOptions.responsive = true;
    chartOptions.maintainAspectRatio = false;
    chartOptions.layout = chartOptions.layout || {};
    chartOptions.layout.padding = chartOptions.layout.padding || 10;
    
    const config = {
        type: instance.config.chartType,
        data: instance.data,
        options: chartOptions
    };
    
    // 添加点击事件监听器
    config.options.onClick = function(event, elements) {
        if (elements.length > 0) {
            const elementIndex = elements[0].index;
            const label = instance.data.labels[elementIndex];
            const trades = instance.data.fullTradeDetails && instance.data.fullTradeDetails[elementIndex] ? instance.data.fullTradeDetails[elementIndex] : [];
            const tradeCount = instance.data.tradeCounts && instance.data.tradeCounts[elementIndex] ? instance.data.tradeCounts[elementIndex] : 0;
            
            console.log('点击图表元素:', {
                elementIndex,
                label,
                tradesCount: trades.length,
                tradeCount
            });
            
            if (trades.length > 0) {
                ew_showTradeDetailsModal(label, trades, tradeCount);
            } else {
                alert('该数据点没有关联的交易详情');
            }
        }
    };
    
    instance.chart = new Chart(ctx, config);
}

// 重写ew_showChartConfig函数以支持多图表
const originalShowChartConfig = ew_showChartConfig;
window.ew_showChartConfig = function() {
    if (window.chartInstances.length === 0) {
        // 没有图表，询问是否创建新图表
        if (confirm('没有可用的图表，是否创建新图表？')) {
            ew_addNewChart();
        }
        return;
    }
    
    if (!window.currentChartId) {
        // 有图表但没选择，提示用户选择图表
        alert('请先点击图表上的配置按钮选择要配置的图表');
        return;
    }
    
    // 显示配置面板
    return originalShowChartConfig();
};

// 重写配置相关函数以支持多图表
const originalUpdateCustomChart = ew_updateCustomChart;
window.ew_updateCustomChart = function() {
    if (window.currentChartId) {
        // 获取当前配置面板的配置
        const currentConfig = ew_getChartConfig();
        
        // 更新当前图表实例的配置
        const instance = window.chartInstances.find(c => c.id === window.currentChartId);
        if (instance) {
            instance.config = currentConfig;
            
            // 更新图表标题（如果配置中有标题）
            if (currentConfig.chartTitle) {
                instance.title = currentConfig.chartTitle;
            }
            
            // 更新图表
            ew_updateSingleChart(window.currentChartId);
            
            // 更新配置摘要显示
            setTimeout(() => {
                ew_updateChartConfigSummary(window.currentChartId);
                // 自动保存状态
                ew_autoSaveChartState();
            }, 100);
        }
    } else {
        // 如果没有选中图表，使用原来的函数（兼容性）
        return originalUpdateCustomChart();
    }
};

// 更新图表配置摘要
function ew_updateChartConfigSummary(chartId) {
    const instance = window.chartInstances.find(c => c.id === chartId);
    if (!instance) return;
    
    const summaryEl = document.querySelector(`#chartInstance_${chartId} .chart-config-summary`);
    if (summaryEl) {
        summaryEl.textContent = ew_getChartConfigSummary(instance.config);
    }
    
    // 更新标题
    const titleEl = document.querySelector(`#chartInstance_${chartId} .chart-instance-title`);
    if (titleEl) {
        titleEl.textContent = instance.title;
    }
}

// 重写快速配置应用函数以支持多图表
const originalApplyQuickConfig = ew_applyQuickConfig;
window.ew_applyQuickConfig = function(configId) {
    if (window.currentChartId) {
        // 先显示加载状态
        const btn = document.querySelector(`[onclick="ew_applyQuickConfig(${configId})"]`);
        const originalText = btn.innerHTML;
        btn.innerHTML = '<i class="fas fa-spinner fa-spin me-1"></i>应用中...';
        btn.disabled = true;
        
        // 清除其他按钮的活动状态
        document.querySelectorAll('.quick-config-btn').forEach(otherBtn => {
            if (otherBtn !== btn) {
                otherBtn.classList.remove('active');
            }
        });
        
        $.get('/statistics/saved_chart_configs', function(data) {
            const configs = data.configs || [];
            const targetConfig = configs.find(c => c.id === configId);
            
            if (targetConfig) {
                // 应用配置到配置面板
                ew_applyChartConfig(targetConfig.config);
                
                // 显示成功提示
                btn.innerHTML = '<i class="fas fa-check text-success me-1"></i>已应用';
                btn.classList.add('active');
                
                // 自动更新当前图表
                setTimeout(() => {
                    ew_updateCustomChart();
                }, 200);
                
                // 恢复按钮状态
                setTimeout(() => {
                    btn.innerHTML = originalText;
                    btn.disabled = false;
                    btn.classList.remove('active');
                }, 2000);
            } else {
                // 配置不存在
                btn.innerHTML = '<i class="fas fa-exclamation-triangle text-warning me-1"></i>配置不存在';
                setTimeout(() => {
                    btn.innerHTML = originalText;
                    btn.disabled = false;
                }, 2000);
            }
        }).fail(function() {
            // 加载失败
            btn.innerHTML = '<i class="fas fa-exclamation-triangle text-danger me-1"></i>加载失败';
            setTimeout(() => {
                btn.innerHTML = originalText;
                btn.disabled = false;
            }, 2000);
        });
    } else {
        // 如果没有选中图表，提示用户
        const btn = document.querySelector(`[onclick="ew_applyQuickConfig(${configId})"]`);
        const originalText = btn.innerHTML;
        
        if (window.chartInstances.length === 0) {
            // 没有图表，询问是否创建新图表
            if (confirm('没有可用的图表，是否创建新图表并应用此配置？')) {
                ew_addNewChart();
                setTimeout(() => {
                    ew_applyQuickConfig(configId);
                }, 300);
            }
        } else {
            // 有图表但没选择，提示用户选择
            btn.innerHTML = '<i class="fas fa-exclamation-triangle text-warning me-1"></i>请先选择图表';
            btn.disabled = true;
            setTimeout(() => {
                btn.innerHTML = originalText;
                btn.disabled = false;
            }, 2000);
        }
         }
 };

// 多图表状态保存和加载
function ew_saveMultiChartState() {
    if (!window.chartInstances || window.chartInstances.length === 0) {
        console.log('没有图表需要保存');
        return Promise.resolve();
    }
    
    // 准备保存的数据 - 只保存配置，不保存实际的图表对象和数据
    const chartInstancesForSave = window.chartInstances.map(instance => ({
        id: instance.id,
        title: instance.title,
        config: instance.config
        // 不保存chart和data，这些将在加载时重新生成
    }));
    
    const data = {
        chartInstances: chartInstancesForSave
    };
    
    return $.ajax({
        url: '/statistics/multi_chart_state',
        type: 'POST',
        contentType: 'application/json',
        data: JSON.stringify(data),
        success: function(response) {
            if (response.success) {
                console.log('图表状态保存成功');
                // 显示成功提示
                ew_showSaveSuccessMessage();
            } else {
                console.error('图表状态保存失败:', response.error);
                alert('保存失败: ' + response.error);
            }
        },
        error: function(xhr) {
            console.error('图表状态保存失败:', xhr.responseText);
        }
    });
}

function ew_loadMultiChartState() {
    return $.get('/statistics/multi_chart_state', function(response) {
        if (response.success && response.state && response.state.chartInstances) {
            const savedInstances = response.state.chartInstances;
            
            // 清空现有图表
            window.chartInstances = [];
            
            // 重建图表实例（不包含数据，将在渲染时重新生成）
            savedInstances.forEach(savedInstance => {
                const instance = {
                    id: savedInstance.id,
                    title: savedInstance.title,
                    config: savedInstance.config,
                    chart: null,
                    data: null
                };
                window.chartInstances.push(instance);
            });
            
            // 更新chartIdCounter确保新图表ID不重复
            const maxId = Math.max(...window.chartInstances.map(i => {
                const match = i.id.match(/chart_(\d+)/);
                return match ? parseInt(match[1]) : 0;
            }), 0);
            window.chartIdCounter = maxId + 1;
            
            // 重新渲染所有图表
            ew_renderAllCharts();
            
            // 异步更新所有图表数据
            setTimeout(() => {
                window.chartInstances.forEach(instance => {
                    ew_updateSingleChart(instance.id);
                });
            }, 100);
            
            // 恢复快速配置按钮状态
            ew_restoreQuickConfigButtons();
            
            console.log(`成功加载 ${savedInstances.length} 个图表`);
        } else {
            console.log('没有保存的图表状态');
        }
    }).fail(function(xhr) {
        console.error('加载图表状态失败:', xhr.responseText);
    });
}

function ew_autoSaveChartState() {
    // 防抖保存，避免频繁保存
    if (window.autoSaveTimeout) {
        clearTimeout(window.autoSaveTimeout);
    }
    
    window.autoSaveTimeout = setTimeout(() => {
        ew_saveMultiChartState();
    }, 1000); // 1秒后自动保存
}

function ew_showSaveSuccessMessage() {
    // 创建一个临时的成功提示
    const message = document.createElement('div');
    message.className = 'alert alert-success alert-dismissible fade show position-fixed';
    message.style.cssText = 'top: 20px; right: 20px; z-index: 9999; min-width: 300px;';
    message.innerHTML = `
        <i class="fas fa-check-circle me-2"></i>
        图表状态已保存成功！
        <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
    `;
    
    document.body.appendChild(message);
    
    // 3秒后自动消失
    setTimeout(() => {
        if (message.parentNode) {
            message.parentNode.removeChild(message);
        }
    }, 3000);
}

// 批量操作函数
function ew_refreshAllCharts() {
    if (window.chartInstances.length === 0) {
        alert('没有可刷新的图表');
        return;
    }
    
    if (!confirm(`确定要刷新所有 ${window.chartInstances.length} 个图表吗？`)) {
        return;
    }
    
    // 显示进度提示
    const btn = document.querySelector('[onclick="ew_refreshAllCharts()"]');
    const originalText = btn.innerHTML;
    let currentIndex = 0;
    
    btn.innerHTML = `<i class="fas fa-spinner fa-spin me-1"></i>刷新中 (0/${window.chartInstances.length})`;
    btn.disabled = true;
    
    // 依次刷新每个图表
    const refreshNext = () => {
        if (currentIndex >= window.chartInstances.length) {
            // 全部完成
            btn.innerHTML = '<i class="fas fa-check text-success me-1"></i>刷新完成';
            setTimeout(() => {
                btn.innerHTML = originalText;
                btn.disabled = false;
            }, 2000);
            return;
        }
        
        const instance = window.chartInstances[currentIndex];
        btn.innerHTML = `<i class="fas fa-spinner fa-spin me-1"></i>刷新中 (${currentIndex + 1}/${window.chartInstances.length})`;
        
        ew_updateSingleChart(instance.id).then(() => {
            currentIndex++;
            setTimeout(refreshNext, 500); // 延迟500ms避免过快请求
        }).catch(() => {
            currentIndex++;
            setTimeout(refreshNext, 500);
        });
    };
    
    refreshNext();
}

function ew_clearAllCharts() {
    if (window.chartInstances.length === 0) {
        alert('没有可清除的图表');
        return;
    }
    
    if (!confirm(`确定要清除所有 ${window.chartInstances.length} 个图表吗？此操作不可撤销。`)) {
        return;
    }
    
    // 销毁所有图表实例
    window.chartInstances.forEach(instance => {
        if (instance.chart) {
            instance.chart.destroy();
        }
    });
    
    // 清空数组
    window.chartInstances = [];
    window.currentChartId = null;
    
    // 隐藏配置面板
    ew_hideChartConfig();
    
    // 更新显示
    ew_updateMultiChartDisplay();
}
 
 // 在页面加载时初始化图表配置管理
$(document).ready(function() {
    // 加载已保存的图表配置
    ew_loadSavedChartConfigs();
    
    // 初始化快速配置设置
    ew_loadQuickConfigSettings().then(() => {
        console.log('快速配置设置加载完成');
        // 确保快速配置按钮状态正常
        setTimeout(() => {
            ew_restoreQuickConfigButtons();
        }, 1000);
    });
    
    // 在页面卸载前自动保存图表状态
    window.addEventListener('beforeunload', function() {
        if (window.chartInstances && window.chartInstances.length > 0) {
            // 使用sendBeacon进行最后的保存
            const data = JSON.stringify({
                chartInstances: window.chartInstances.map(instance => ({
                    id: instance.id,
                    title: instance.title,
                    config: instance.config
                }))
            });
            
            const blob = new Blob([data], { type: 'application/json' });
            navigator.sendBeacon('/statistics/multi_chart_state', blob);
        }
    });
});

// ==================== 快速配置管理功能 ====================

// 全局变量存储快速配置设置
window.quickConfigSettings = {
    configs: [],
    limit: 10,
    style: 'outline'
};

// 显示快速配置管理界面
function ew_showQuickConfigManager() {
    // 加载当前快速配置设置
    ew_loadQuickConfigSettings().then(() => {
        // 渲染快速配置列表
        ew_renderQuickConfigList();
        
        // 设置界面值
        document.getElementById('quickConfigLimit').value = window.quickConfigSettings.limit;
        document.getElementById('quickConfigStyle').value = window.quickConfigSettings.style;
        
        // 显示模态框
        const modal = new bootstrap.Modal(document.getElementById('quickConfigManagerModal'));
        modal.show();
    });
}

// 渲染快速配置列表
function ew_renderQuickConfigList() {
    const container = document.getElementById('quickConfigList');
    
    if (window.quickConfigSettings.configs.length === 0) {
        container.innerHTML = `
            <div class="text-center text-muted py-4">
                <i class="fas fa-inbox fa-2x mb-2"></i>
                <div>暂无快速配置</div>
                <small>点击上方的"从所有配置中添加"按钮来添加快速配置</small>
            </div>
        `;
        return;
    }
    
    let html = '';
    window.quickConfigSettings.configs.forEach((config, index) => {
        const summary = ew_getChartConfigSummary(config.config);
        html += `
            <div class="quick-config-item card mb-2" data-config-id="${config.id}" style="cursor: move;">
                <div class="card-body p-3">
                    <div class="d-flex justify-content-between align-items-start">
                        <div class="flex-grow-1">
                            <div class="d-flex align-items-center mb-2">
                                <i class="fas fa-grip-vertical text-muted me-2" title="拖拽排序"></i>
                                <h6 class="mb-0">${config.name}</h6>
                                <span class="badge bg-secondary ms-2">#${index + 1}</span>
                            </div>
                            <small class="text-muted">${summary}</small>
                        </div>
                        <div class="d-flex gap-1">
                            <button class="btn btn-sm btn-outline-primary" onclick="ew_editQuickConfigName(${config.id}, '${config.name.replace(/'/g, "\\\'")}')" title="重命名">
                                <i class="fas fa-edit"></i>
                            </button>
                            <button class="btn btn-sm btn-outline-danger" onclick="ew_removeFromQuickConfigs(${config.id})" title="移除">
                                <i class="fas fa-times"></i>
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        `;
    });
    
    container.innerHTML = html;
    
    // 初始化拖拽排序
    if (window.Sortable) {
        new Sortable(container, {
            animation: 150,
            handle: '.fas.fa-grip-vertical',
            onEnd: function(evt) {
                // 更新配置顺序
                const oldIndex = evt.oldIndex;
                const newIndex = evt.newIndex;
                
                if (oldIndex !== newIndex) {
                    const configs = window.quickConfigSettings.configs;
                    const movedConfig = configs.splice(oldIndex, 1)[0];
                    configs.splice(newIndex, 0, movedConfig);
                    
                    // 重新渲染列表以更新序号
                    ew_renderQuickConfigList();
                }
            }
        });
    }
}

// 从所有配置中添加到快速配置
function ew_addToQuickConfigs() {
    $.get('/statistics/saved_chart_configs', function(data) {
        const allConfigs = data.configs || [];
        const currentQuickIds = window.quickConfigSettings.configs.map(c => c.id);
        const availableConfigs = allConfigs.filter(c => !currentQuickIds.includes(c.id));
        
        if (availableConfigs.length === 0) {
            alert('所有配置都已添加到快速配置中');
            return;
        }
        
        // 创建选择界面
        let html = '';
        
        if (availableConfigs.length > 0) {
            html = `
                <div class="mb-3">
                    <div class="d-flex justify-content-between align-items-center">
                        <h6>选择要添加的配置：</h6>
                        <div>
                            <button class="btn btn-sm btn-outline-primary" onclick="ew_selectAllConfigs(true)">全选</button>
                            <button class="btn btn-sm btn-outline-secondary" onclick="ew_selectAllConfigs(false)">取消全选</button>
                        </div>
                    </div>
                </div>
            `;
            
            availableConfigs.forEach(config => {
                const summary = ew_getChartConfigSummary(config.config);
                html += `
                    <div class="form-check mb-3">
                        <input class="form-check-input" type="checkbox" value="${config.id}" id="available_config_${config.id}">
                        <label class="form-check-label" for="available_config_${config.id}">
                            <div class="fw-bold">${config.name}</div>
                            <small class="text-muted">${summary}</small>
                            <div class="text-muted small mt-1">创建时间: ${config.created_at}</div>
                        </label>
                    </div>
                `;
            });
        }
        
        // 显示在新模态框中
        const container = document.getElementById('availableConfigsList');
        container.innerHTML = html;
        
        // 显示模态框
        const addModal = new bootstrap.Modal(document.getElementById('addQuickConfigModal'));
        addModal.show();
        
        // 绑定确认按钮事件
        document.getElementById('confirmAddConfigs').onclick = ew_confirmAddToQuickConfigs;
        
    }).fail(function() {
        alert('加载配置失败');
    });
}

// 全选/取消全选配置
function ew_selectAllConfigs(select) {
    const checkboxes = document.querySelectorAll('#availableConfigsList input[type="checkbox"]');
    checkboxes.forEach(checkbox => {
        checkbox.checked = select;
    });
}

// 确认添加选中的配置
function ew_confirmAddToQuickConfigs() {
    const checkboxes = document.querySelectorAll('#availableConfigsList input[type="checkbox"]:checked');
    const selectedIds = Array.from(checkboxes).map(cb => parseInt(cb.value));
    
    if (selectedIds.length === 0) {
        alert('请选择至少一个配置');
        return;
    }
    
    // 检查是否超过限制
    const currentCount = window.quickConfigSettings.configs.length;
    const limit = window.quickConfigSettings.limit;
    const availableSlots = limit - currentCount;
    
    if (selectedIds.length > availableSlots) {
        if (!confirm(`选中了 ${selectedIds.length} 个配置，但只能添加 ${availableSlots} 个（当前限制：${limit}）。是否只添加前 ${availableSlots} 个？`)) {
            return;
        }
    }
    
    // 从服务器获取配置详情并添加
    $.get('/statistics/saved_chart_configs', function(data) {
        const allConfigs = data.configs || [];
        let addedCount = 0;
        
        selectedIds.forEach(configId => {
            const config = allConfigs.find(c => c.id === configId);
            if (config && window.quickConfigSettings.configs.length < window.quickConfigSettings.limit) {
                window.quickConfigSettings.configs.push(config);
                addedCount++;
            }
        });
        
        // 关闭添加模态框
        const addModal = bootstrap.Modal.getInstance(document.getElementById('addQuickConfigModal'));
        if (addModal) {
            addModal.hide();
        }
        
        // 重新渲染快速配置列表
        ew_renderQuickConfigList();
        
        // 显示成功消息
        if (addedCount > 0) {
            alert(`成功添加了 ${addedCount} 个配置到快速配置中`);
        }
        
    }).fail(function() {
        alert('加载配置失败');
    });
}



// 编辑快速配置名称
function ew_editQuickConfigName(configId, currentName) {
    const newName = prompt('请输入新的配置名称:', currentName);
    if (newName && newName.trim() && newName !== currentName) {
        // 更新本地配置
        const config = window.quickConfigSettings.configs.find(c => c.id === configId);
        if (config) {
            config.name = newName.trim();
            ew_renderQuickConfigList();
        }
        
        // 同时更新服务器上的配置
        ew_updateChartConfig(configId, newName.trim());
    }
}

// 从快速配置中移除
function ew_removeFromQuickConfigs(configId) {
    const config = window.quickConfigSettings.configs.find(c => c.id === configId);
    if (config && confirm(`确定要从快速配置中移除 "${config.name}" 吗？`)) {
        window.quickConfigSettings.configs = window.quickConfigSettings.configs.filter(c => c.id !== configId);
        ew_renderQuickConfigList();
    }
}

// 保存快速配置设置
function ew_saveQuickConfigSettings() {
    // 获取设置值
    window.quickConfigSettings.limit = parseInt(document.getElementById('quickConfigLimit').value) || 10;
    window.quickConfigSettings.style = document.getElementById('quickConfigStyle').value || 'outline';
    
    // 限制配置数量
    if (window.quickConfigSettings.configs.length > window.quickConfigSettings.limit) {
        window.quickConfigSettings.configs = window.quickConfigSettings.configs.slice(0, window.quickConfigSettings.limit);
    }
    
    // 保存到服务器
    $.ajax({
        url: '/statistics/quick_config_settings',
        type: 'POST',
        contentType: 'application/json',
        data: JSON.stringify(window.quickConfigSettings),
        success: function(response) {
            if (response.success) {
                // 关闭模态框
                const modal = bootstrap.Modal.getInstance(document.getElementById('quickConfigManagerModal'));
                modal.hide();
                
                // 刷新快速配置按钮
                ew_refreshQuickConfigs();
                
                // 显示成功消息
                ew_showSaveSuccessMessage();
            } else {
                alert('保存失败: ' + response.error);
            }
        },
        error: function() {
            alert('保存失败，请重试');
        }
    });
}

// 加载快速配置设置
function ew_loadQuickConfigSettings() {
    return $.get('/statistics/quick_config_settings')
        .done(function(response) {
            if (response.success && response.settings) {
                window.quickConfigSettings = response.settings;
            }
        })
        .fail(function() {
            console.log('加载快速配置设置失败，使用默认设置');
        });
}